2016-11-24 20 views
0

私は、(私がコントロールしていない)あまり書かれていないPythonモジュールをクラスにラップしようとしています。問題は、モジュールのclose関数を明示的に呼び出さないと、終了時にPythonプロセスがハングするため、delメソッドを持つクラスでモジュールをラップしようとしましたが、delメソッドは行います例外に関しては呼び出されないようです。Python __del__は例外で呼び出されません

例:この場合

class Test(object): 
    def __init__(self): 
     # Initialize the problematic module here 
     print "Initializing" 

    def __del__(self): 
     # Close the problematic module here 
     print "Closing" 

t = Test() 
# This raises an exception 
moo() 

デルが呼び出され、Pythonのハングアップされていません。私は何とかPythonがdelを呼び出すように、オブジェクトがスコープから外れるとすぐに(C++のように)強制する必要があります。 私は問題のあるモジュール(つまり、これを最初に引き起こすバグを修正できません)とラッパークラスを使用する人を制御できないことに注意してください( "with"を使用するよう強制することはできません。 出口を使用してください)。

これを解決する方法はありますか?

ありがとうございます!

+0

__del__は使用しないでください。これはC++やデストラクタ向けに作られた言語ではありません。 Python 3.xでは__del__メソッドが本当になくてはなりませんが、誰かが合理的なユースケースを見つけられると確信しています。 __del__を使用する必要がある場合は、http://docs.python.org/reference/datamodel.html – harshil9968

+1

の基本的な制限に注意してください。 – jonrsharpe

+0

私が言ったように、私はクラスを使う人を誰も制御できません。私は彼らに "with"を使用させることはできません。 – Dan

答えて

1

例外でリソースを解放したい場合は、__enter__ + __exit__パラダイムについて考えてください。

class Test(object): 
    def __enter__(self): 
     pass 

    def __exit__(self): 
     pass # Release your resources here 

with Test() as t: 
    moo() 

実行はブロック「と」、「T」の方法__enterの__()が呼び出され、それが原因通常の流れ、または例外のいずれかにブロックを残す、方法__exitの__(に入ります)の 't'が呼び出されます。

+0

コメントの最後の部分に注意してください - 私はラッパークラスを使用する人や、どのように使用されるかを制御できません。つまり、強制的に "with"を使用することはできません。すべてのソリューションは、ラッパークラスコード内でのみ実装する必要があります。 – Dan

+0

OKですが、クラスを使用するコードを制御できますか?そのクライアントコードで\ _ \ _ enter \ _ \ _/\ _ \ _ exit \ _ \ _を使用することができます。私はその考えを説明するためにTestクラスを置いた。入退出物を実装する他の方法もあります。 @ contextlib.contextmangerを使用します。 –

+0

こんにちは、私はクラスを使用するコードを制御する必要はありません。 – Dan

関連する問題