Python上下文管理器

  注意一下代碼:spa

  

def try_method():
    try:
        print('code started')
        raise KeyError
        return 1

    except KeyError as e:
        print('keyerror')
        return 2

    finally:
        print('finally')
        return 4

s = try_method()
print(s)
輸出結果:
code started
keyerror
finally
4

關於最後結果爲什不是2?code

  在except語句中是捕捉到了KeyError錯誤。return2,此時會將結果2壓入到棧中,而後會繼續執行finally語句,finally語句return4後繼續壓入到棧中,而後s的值爲從棧中取出blog

的值,即爲4而不是2,若是finally最後沒有reuturn結果,那麼s的值就爲2。資源

  要使得本身定義的類知足上下文管理器協議,類中必須定義一下連個魔法方法:it

1:__enter__()class

2:__exit__()import

例:file

class Sample():
    def __enter__(self):
        print('Enter')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('Exit')

    def do_something(self):
        print('doing something')
with Sample() as s:
    s.do_something()
輸出結果:
Enter
doing something
Exit

 

  用with調用類開始調用的時候,會執行__enter__()方法,調用完成退出的時候必定會執行類中的__exit__()方法。因而最後悔打印出Exit。利用此能夠在__enter__()方法中獲取資源, 而後再__exit__()中釋放資源。yield

更加簡單的方式用contextlib:方法

import contextlib
@contextlib.contextmanager
def open(file_name):
    print('file wil be opened')
    yield 'something'
    print('file ended')
with open('**.txt') as f:
    print('file processing')
輸出結果:
file wil be opened
file processing
file ended

 在yield語句以前語句就至關於__enter__()內的語句。yield以後的語句至關於__exit__()內的語句。所以都會會執行file ended。

相關文章
相關標籤/搜索