2013-08-12 6 views
5

私は、Pythonでのnoobだけど、私はこのようなオートクローズ機能を書いた..自動閉鎖クラスを作成するPythonicの方法は何ですか?

@contextmanager 
def AutoClose(obj): 
    try: 
     yield obj 
    finally: 
     obj.Close() 

私はこの機能を一緒に使用することができます閉じる()メソッドを持っている3つのクラスがあります。これは最もPythonicなソリューションですか?代わりに私はクラスそのもので何かをしなければならないでしょうか?

+0

これは良いようです。あなたのクラスでデストラクタを使うこともできます。 – akiniwa

+1

私はデストラクタ(つまり '__del__')を使わないでください。それがいつ呼び出されるのかについて、本当に考えるのは難しいです。ここで受け入れられた答えを参照してください:http://stackoverflow.com/questions/1935153/del-method-being-called-in-python-when-it-is-not-expected – tom

答えて

8

あなたがやっていることはまったくうまくいっていて、Pythonicに見えます。 contextlib標準ライブラリにはすでに類似点がありますが、Closeメソッドの名前をcloseに変更する必要があります。

import contextlib 
with contextlib.closing(thing): 
    print thing 

これを代わりに使用することをおすすめします。結局のところ、Pythonメソッドの推奨命名規則はall_lowercase_with_underscoresです。

class Foo(object): 
    def __init__(self, filename): 
     self.filename = filename 

    def __enter__(self): 
     self.fd = open(self.filename) 

    def __exit__(self, exc_type, exc_value, traceback): 
     self.fd.close() 

と使用:ブロックwithを入力し、出るとき

with Foo('/path/to/file') as foo: 
    # do something with foo 

方法__enter____exit__が暗黙的に呼び出されます

+0

「bluedog」は、名前を変更する必要がありますcontextlib.closing()を使用するために、自分の(または彼女の).Close()メソッドを.close()してください(私が間違っていない限り)。 –

+0

私は現在のケースでClose()メソッドを保持する必要がありますが、標準のcontextlib.closing関数を使用できるようにclose()という別名を追加することがあります。 – bluedog

9

ほとんどの神託のソリューションは、方法をあなたのクラスの__enter__ and __exit__メソッドを定義することです。また、__exit__は、ブロックwithの内部で発生した例外をキャッチすることができます。

機能contextlib.closingは通常、明示的な方法__enter____exit__を定義します(ただし、メソッドcloseを持って)いないそれらのクラスのために使用されています。独自のクラスを定義する場合は、これらのメソッドを定義する方がはるかに優れています。

+0

+1 - これはIMOにも同様に良い答えです。この機会に私が使用する解決策であるので、私は@トムの答えを選んだ。 3つの特定のクラスはすべてClose()メソッドを持ち、\ _ \ _ enter \ _ \ _を必要としないので、クラスauto_closeを3つすべてのクラスに使用することはできません。 – bluedog

関連する問題