5

__enter__次のように定義された__exit__メソッドを持つクラスがあるとします。

class MyClass:
    def f(self):
        raise Exception
    def __enter__(self): 
        return self
    def __exit__(self, type, value, traceback):
        pass

ブロック内で例外が発生した場合、次のwithようになります。

with MyClass() as ins:
    ins.f()

__exit__メソッドは暗黙的に呼び出されます。これは非常に優れています。

ただし、クラスが次のような場合:

class MyClass:
    def __init__(self):
        self.f()
    def f(self):
        raise Exception
    def __enter__(self): 
        return self
    def __exit__(self, type, value, traceback):
        pass

そして、次のようにインスタンス化します。

with MyClass() as ins:
    pass

__init__メソッド内で例外が発生した場合、__enter__まだ__exit__呼び出されておらず、呼び出しも解除されますが、これはあまり良くありません。これを改善する最善の方法は何ですか?

4

2 に答える 2

2

他の人が指摘したように、あなたがやろうとしていることは厄介なので、きれいな方法はありません。

簡単な方法は次のとおりです。

で何かをクリーンアップしたい場合は__exit__、 で初期化し __enter__ます。

例えば

class MyClass:
    def f(self):
        raise Exception
    def __enter__(self):
        print 'in __enter__'
        # acquire it here...
        return self
    def __exit__(self, type, value, traceback):
        print 'in __exit__'
        # release it here...

with MyClass() as ins:
    print 'calling f()'
    ins.f()
于 2013-07-01T20:36:07.773 に答える