2017-09-06 10 views
1

私は、Pythonでコンテキストマネージャを使用します。私の__exit__メソッドからいくつかのログを取得したいPythonコンテキストマネージャから__exit__の戻り値を取得できますか?

class MyContextManager: 
    def __init__(self, value1, value2) 
     self.value1 = value1 
     self.value2 = value2 

    def __enter__(self) 
     # Do some other stuff 
     return self 

    def __exit__(self, exc_type, exc_val, exc_tb): 
     # Do some tear down action, process some data that is 
     # created in __enter__ and log those results 
     return my_results 

with MyContextManager(value1=my_value1, value2=my_value2) as manager: 
    # Do some stuff 

それでは、どのように私は私の持つブロックの後(または末尾)__exit__から返されmy_resultsにアクセスできます。だから私のコードは次のようなものを記録します。これは__exit__メソッドでTrue以外の何かを返すことは合法ですか?

答えて

3

これは__exit__メソッドでTrue以外の何かを返すことは正当なものですか?

いいえ、実際はそうではありませんが、Pythonはtruth valueをテストするだけで、それを手放すことができます。言い換えれば、ここで真実のオブジェクトを返すと、例外はすべて抑止されます。例外がなければ真理値を返すのはノーオペレーションだけです。

ブロックされたmyの後(または最後に)__exit__から返されるmy_resultsにどのようにアクセスできますか。

できません。 with表現機械がそれを消費しました。

他の方法で利用できるようにする必要があります。コンテキストマネージャオブジェクト自体の属性として設定します:

class MyContextManager: 
    def __init__(self, value1, value2) 
     self.value1 = value1 
     self.value2 = value2 

    def __enter__(self) 
     # Do some other stuff 
     return self 

    def __exit__(self, exc_type, exc_val, exc_tb): 
     # Do some tear down action, process some data that is 
     # created in __enter__ and log those results 
     self.my_results = my_results 
     # returning None, we don't want to suppress exceptions 
     return None 

with MyContextManager(value1=my_value1, value2=my_value2) as manager: 
    # Do some stuff 

results = manager.my_results 

withブロックが完了した後manager名が利用可能です。

これは、たとえば、unittest.TestCase.assertRaises() context managerがキャプチャされた例外を共有する方法です。

+0

ありがとうございます!役に立つ情報! :)私は、MyContextManagerのインスタンスがwithブロックの後にまだ生きていることを知らなかった。 –

+0

助けてくれてうれしい!あなたがそれが役に立ったと思ったら、[私の答えを受け入れる](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)を自由に感じてください。 :-) –

関連する問題