それ自体でコンテキストマネージャーとして機能するクラス「A」があるとしましょう。
def __enter__()
def __exit__()
インターフェース。with
クライアント コードがステートメントを使用して直接 'A' オブジェクトを作成することは有効です。
現在、他の機能をカプセル化し、「A」オブジェクトを利用する別のクラス「B」もあります。
「B」をコンテキスト マネージャーとしても機能させたい場合、「A」インスタンスを管理する正しい方法は何ですか?
'B' 呼び出しの実装と(それぞれ) その A オブジェクト インスタンスの実装は必要__enter__
ですか? それとももっと良い方法がありますか?__exit__
__enter__
__exit__
具体的な例を挙げると (これは私のアプリケーションで使用しているものではありません。頭に浮かんだ最初の非抽象的な例です)、2 つのクラスを考えます。
DatabaseConnection
DatabaseConnectionPool
DatabaseConnection
単一のものを単独で使用することは有効であるためDatabaseConnection
、context-manager インターフェースを実装します。
DatabaseConnectionPool
DatabaseConnections
他のビットとボブだけでなく、いくつかを利用します。を使用するDatabaseConnectionPool
と (つまり、"with" で)、そのインスタンスのセットアップと破棄が行われDatabaseConnection
ます (その他に必要なことは何でも実行されます)。
更新: 次の出力が得られることを望んでいたテスト コードをいくつか作成しました。
Enter は Outer で呼び出されます インナーで呼び出された入力 外部コンテキスト内で... do_foo が呼び出されました! まだアウターを使っている... 内部で呼び出される終了 外部で呼び出された終了 アウターを使って完成
しかし、私は以下を得ました:
Enter は Outer で呼び出されます インナーで呼び出された入力 内部で呼び出される終了 外部コンテキスト内で... do_foo が呼び出されました! まだアウターを使っている... 外部で呼び出された終了 アウターを使って完成
コード:
class Inner(object):
def __enter__(self):
print "Enter invoked on Inner"
return self
def __exit__(self, typ, val, tb):
print "Exit invoked on inner"
def do_foo(self):
print "do_foo invoked!"
class Outer(object):
def __init__(self):
self._inner = Inner()
def __enter__(self):
print "Enter invoked on Outer"
with self._inner as ctx:
return self
def __exit__(self, typ, val, tb):
print "Exit invoked on outer"
with Outer() as outer:
print "Within outer context..."
outer._inner.do_foo()
print "Still using outer..."
print "Done using outer"
これを機能させる方法についてのアイデアはありますか?