面向對象高階-10上下文管理

what python中的上下文

這個概念屬於語言學科,指的是一段話的意義,要參考當前的場景,既上下文
在python中,上下文能夠理解爲是一個代碼區間,一個範圍 ,例如with open 打開的文件僅在這個上下文中有效python

  • 咱們知道在操做文件對象的時候能夠這麼寫
with open('a.txt') as f:
    '代碼塊'
  • 上述叫作上下文管理協議,即with語句,爲了讓一個對象兼容with語句,必須在這個對象的類中聲明__enter__和__exit__方法


牽扯到2個魔法方法

  • __enter__
  • __exit__


上下文管理協議

上代碼編程

class Open:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print('出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量')
        # return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with中代碼塊執行完畢時執行我啊')


with Open('a.txt') as f:
    print('=====>執行代碼塊')
    # print(f,f.name)

出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量
=====>執行代碼塊
with中代碼塊執行完畢時執行我啊網絡

  • __exit__()中的三個參數分別表明異常類型,異常值和追溯信息,with語句中代碼塊出現異常,則with後的代碼都沒法執行

上代碼app

class Open:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print('出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with中代碼塊執行完畢時執行我啊')
        print(exc_type)
        print(exc_val)
        print(exc_tb)


try:
    with Open('a.txt') as f:
        print('=====>執行代碼塊')
        raise AttributeError('***着火啦,救火啊***')
except Exception as e:
    print(e)

出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量
=====>執行代碼塊
with中代碼塊執行完畢時執行我啊
<class 'AttributeError'>
\\\着火啦,救火啊\\\
<traceback object at 0x1065f1f88>
\\\着火啦,救火啊\\\code

  • 若是__exit()返回值爲True,那麼異常會被清空,就好像啥都沒發生同樣,with後的語句正常執行
class Open:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print('出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with中代碼塊執行完畢時執行我啊')
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        return True


with Open('a.txt') as f:
    print('=====>執行代碼塊')
    raise AttributeError('***着火啦,救火啊***')
print('0' * 10)  #------------------------------->會執行

出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量
=====>執行代碼塊
with中代碼塊執行完畢時執行我啊
<class 'AttributeError'>
***着火啦,救火啊***
<traceback object at 0x1062ab048>
0000000000對象


模擬open

列子一utf-8

class Open:
    def __init__(self, filepath, mode='r', encoding='utf-8'):
        self.filepath = filepath
        self.mode = mode
        self.encoding = encoding

    def __enter__(self):
        # print('enter')
        self.f = open(self.filepath, mode=self.mode, encoding=self.encoding)
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        # print('exit')
        self.f.close()
        return True

    def __getattr__(self, item):
        return getattr(self.f, item)


with Open('a.txt', 'w') as f:
    print(f)
    f.write('aaaaaa')
    f.wasdf  #拋出異常,交給__exit__處理

<_io.TextIOWrapper name='a.txt' mode='w' encoding='utf-8'>'
列子二資源

class MyOpen(object):


    def __init__(self,path):
        self.path = path

    def __enter__(self):
        self.file = open(self.path)
        print("enter.....")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exit...")
        # print(exc_type,exc_val,exc_tb)
        self.file.close()
        return True


with MyOpen("a.txt") as m:
    # print(m)
    # print(m.file.read())
    "123"+1

# m.file.read()

優勢

 1.使用with語句的目的就是把代碼塊放入with中執行,with結束後,自動完成清理工做,無須手動干預get

 2.在須要管理一些資源好比文件,網絡鏈接和鎖的編程環境中,能夠在__exit__中定製自動釋放資源的機制,你無須再去關係這個問題,這將大有用處it

相關文章
相關標籤/搜索