Python深入02コンテキストマネージャ

6072 ワード

作者:Vamei出典:http://www.cnblogs.com/vamei 転載を歓迎します.この声明も保留してください.ありがとうございます.
 
コンテキストマネージャ(context manager)は、Python 2.5がサポートを開始する文法であり、あるオブジェクトの使用範囲を規定するために使用されます.この使用範囲に入ると、オブジェクトの割り当てやメモリの解放などの特殊な操作が呼び出されます.その文法形式はwith...as...
 
ファイルを閉じる
ファイルを開けて、読み書きして、ファイルを閉じます.プログラマはファイルを閉じるのを忘れがちです.コンテキストマネージャは、ファイルが必要でないときは、自動的にファイルを閉じます.
次は二つのプログラムを見ます.
# without context manager
f = open("new.txt", "w") print(f.closed)               # whether the file is open
f.write(
"Hello World!") f.close()
print(f.closed)
および:
# with context manager
with open("new.txt", "w") as f:
print(f.closed) f.write(
"Hello World!")

print(f.closed)
二つのプログラムは実際に同じ操作を実行します.私たちの第二段のプログラムは文脈マネージャ(with...as...)を使いました.コンテキストマネージャは、そのプログラムブロックに属するものがあります.付属のプログラムブロックの実行が終了すると、コンテキストマネージャは自動的にファイルを閉じます.私たちは、インデントを使用してファイルオブジェクトfの使用範囲を規定するのに相当します.
 
上のコンテキストマネージャはfオブジェクトの__u uに基づいています.exit_u()特殊な方法(特殊な方法で様々な文法を実現する方法を覚えていますか?特殊な方法と多范式を参照してください.)コンテキストマネージャの文法を使うとき、実際にはPythonがプログラムブロックに入る前にオブジェクトの__u uを呼び出すことを要求します.enter_う()方法は、プログラムブロックを終了するときに_u u_u uを呼び出します.exit_u()方法.ファイルオブジェクトfに対して、__u uを定義しています.enter_う()と_exit_u()方法(dir(f)で見られます).fの_u uにありますexit_u()方法には、self.close()の文があります.だから、文脈マネージャを使う時、私達は明文でfファイルを閉じなくてもいいです.
 
カスタム
どんな定義がありますかenter_う()と_exit_u()メソッドのオブジェクトは、コンテキストマネージャに使用できます.ファイルオブジェクトfは内蔵オブジェクトですので、fは自動的にこの2つの特殊な方法を持っています.カスタムは必要ありません.
次に、コンテキストマネージャの対象をカスタマイズします.次のmyvowです.
 
# customized object

class VOW(object): def __init__(self, text): self.text = text def __enter__(self): self.text = "I say: " + self.text    # add prefix
        return self                          # note: return an object
    def __exit__(self,exc_type,exc_value,traceback): self.text = self.text + "!"          # add suffix
 with VOW("I'm fine") as myvow: print(myvow.text) print(myvow.text)
 
私たちの運行結果は以下の通りです.
I say: I'm fine
I say: I'm fine!
文脈に入る時と文脈を離れる時に、対象のtext属性が変わったことが見られます.(最初のtext属性は「I'm fine」です.)
同前enter_う()オブジェクトを返します.コンテキストマネージャはこのオブジェクトをasの変数、すなわちmyvowとして使用します.呷にいますenter_う()では、myvow.textにプレフィックスを追加しました(「I say:」).呷にいますexit_u()の中で、私たちはmyvow.textのために拡張子を追加しました.
注意してくださいexit_u()には4つのパラメータがあります.プログラムブロックに異常(exception)が発生すると、__exit_u()のパラメータの中でexc_type,exc_value、tracbackは異常を記述するために使用されます.この三つのパラメータに基づいて対応する処理ができます.正常運転が終了すれば、この3つのパラメータはすべてNoneです.私たちのプログラムでは、この特性を使っていません.
 
まとめ:
コンテキストマネージャを通して、プログラムの異なる区間のオブジェクトの特性を制御します.コンテキストマネージャ(with EXPR as VER)は、大体次の流れに相当します.
# with EXPR as VAR:

VAR = EXPR
VAR = VAR.__enter__()
try:
    BLOCK
finally:
    VAR.__exit__()
コンテキストマネージャによってもたらされる便利さのために、使用に値するツールです.