回答:
__del__あるファイナライザは。オブジェクトへのすべての参照が削除された後のある時点でオブジェクトがガベージコレクションされたときに呼び出されます。
では簡単な場合、これはあなたが言う直後ことができdel xた場合、またはx機能が終了した後、ローカル変数です。特に、循環参照がない限り、CPython(標準のPython実装)はすぐにガベージコレクションを実行します。
ただし、これはCPythonの実装の詳細です。唯一必要な Pythonのガベージコレクションのプロパティは、それが起こるということです後、すべての参照が削除されているので、必要ではないかもしれない、この現象が発生した直後とまったく起こらない可能性があります。
さらに、変数は、長い時間のために生きることができる多くの理由、例えばA伝播例外またはも0よりも変数の参照カウント大きなを保つことができるモジュールのイントロスペクションは、変数はの一部にすることができます参照のサイクル - CPythonのガベージコレクションで休憩最もオンすべてではありませんが、そのようなサイクル、さらには定期的にのみ。
実行が保証されていないため、実行する必要のあるコードを絶対に配置しないでください__del__()。このコードはfinally、tryブロックの句またはwithステートメントのコンテキストマネージャーに属しています。しかし、そこにある有効なユースケースのための__del__オブジェクトの場合などは:X参照Yのコピーを保持し、また、Yグローバルでの参照をcache(cache['X -> Y'] = Yそれがために丁寧になります)X.__del__また、キャッシュエントリを削除します。
デストラクタが必要なクリーンアップを(上記のガイドラインに違反して)提供していることがわかっている場合は、メソッドとして特別なものは何もないため、直接呼び出すことができますx.__del__()。明らかに、2回呼び出されることを気にしないことがわかっている場合にのみ、そうするべきです。または、最後の手段として、次を使用してこのメソッドを再定義できます。
type(x).__del__ = my_safe_cleanup_method
__exit__。この文脈では?それは後か前__del__か、それとも一緒に実行されますか?
__del__メソッドはプログラムの終了時にも実行されない場合があり、終了時に実行される__del__場合でも、インタープリターがあなたの周りで自己破壊を行っているときにも正しく機能するメソッドを作成するには、多くのプログラマーが適用するよりも注意深いコーディングが必要です。(CPythonクリーンアップは通常__del__、インタープリターのシャットダウン時に実行するメソッドを取得しますが、それでも十分でない場合があります。デーモンスレッド、Cレベルグローバル、および__del__別のもので作成されたオブジェクト__del__はすべて、__del__メソッドが実行されない
これはより正確な質問ですが、別の質問の回答を書きました。
これは少し意見が分かれた回答です。
使用しないでください__del__。これはC ++やデストラクタ用に構築された言語ではありません。__del__Python 3.xではこのメソッドは実際になくなるはずですが、誰かが意味のあるユースケースを見つけると私は確信しています。を使用する必要がある場合は__del__、http://docs.python.org/reference/datamodel.htmlの基本的な制限に注意してください。
__del__ガベージコレクターがたまたまオブジェクトを収集しているときに呼び出されますdel object。オブジェクトへの最後の参照を失ったときや、を実行したときではありません。__del____del__これがメソッド解決順序(MRO)であるのか、各スーパークラスを呼び出すだけなのかは明確ではありませんが、スーパークラスでanyを呼び出す責任があります。__del__ガベージコレクターは、リンクリストへの最後の参照を失うなど、循環リンクの検出とクリーニングをあきらめることを意味します。gc.garbageから無視されたオブジェクトのリストを取得できます。サイクルを完全に回避するために、弱参照を使用できる場合があります。これは時々議論されます:http : //mail.python.org/pipermail/python-ideas/2009-October/006194.htmlを参照してください。__del__関数は、オブジェクトへの参照を保存し、ガベージコレクションを停止し、ごまかすことができます。__del__は無視されます。__del____new__よりはるかに補完し__init__ます。これは混乱を招きます。説明と落とし穴については、http://www.algorithm.co.il/blogs/programming/python-gotchas-1- del -is-not-the-opposite-of- init /を参照してください。__del__Pythonで「愛されている」子ではありません。sys.exit()のドキュメントには、終了する前にガベージを収集するかどうかが指定されておらず、多くの奇妙な問題があることがわかります。__del__on globalsを呼び出すと、http://bugs.python.org/issue5099などの奇妙な順序の問題が発生します。必要がある__del__場合にも呼ば__init__失敗?長いスレッドについては、http://mail.python.org/pipermail/python-dev/2000-March/thread.html#2423を参照してください。しかし、一方で:
__del__closeステートメントを呼び出すことを忘れないでください。プロの視点については、http://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python/を参照してください__del__。これは通常、ctypesまたは他の特別なリソースを解放することについてです。そして、その__del__機能が気に入らない私の個人的な理由。
__del__たびに、それは30の混乱メッセージに発展します。したがって、使用しない理由を見つけてください__del__。
__del__ではなく、どのように呼び出すかについて__del__、あなたの答えは興味深いです。
この__del__メソッドは、オブジェクトがガベージコレクションされたときに呼び出されます。ただし、必ずしも呼び出されるとは限りません。次のコードは、それだけでは必ずしも機能しません。
del obj
その理由はdel、参照カウントを1つだけ減らすためです。他の何かがオブジェクトへの参照を持っている場合、__del__呼び出されません。
__del__ただし、いくつかの注意事項があります。一般的に、それらは通常、あまり役に立ちません。closeメソッドまたはwithステートメントを使用したいように思えます。
メソッドに関するPythonのドキュメントを__del__参照してください。
もう1つ注意 __del__する必要があるのは、メソッドを使いすぎるとガベージコレクションが禁止されることです。特に、__del__メソッドを持つ複数のオブジェクトを持つ循環参照は、ガベージコレクションされません。これは、ガベージコレクターが最初に呼び出すものを認識していないためです。詳細については、gcモジュールのドキュメントを参照してください。
__del__あなたのオブジェクトが最終的に破棄されたときの方法は、(ノートスペル!)と呼ばれています。技術的に言えば(cPythonで)、オブジェクトへの参照がなくなったとき、つまりオブジェクトがスコープから外れたときです。
オブジェクトを削除して__del__メソッドを呼び出す場合は、use
del obj1
これにより、オブジェクトが削除されます(オブジェクトへの参照が他にない場合)。
このような小さなクラスを書くことをお勧めします
class T:
def __del__(self):
print "deleted"
そして、Pythonインタープリターで調べてください、例えば
>>> a = T()
>>> del a
deleted
>>> a = T()
>>> b = a
>>> del b
>>> del a
deleted
>>> def fn():
... a = T()
... print "exiting fn"
...
>>> fn()
exiting fn
deleted
>>>
jythonとironpythonには、オブジェクトが削除されて__del__呼び出される正確なタイミングに関して異なるルールがあることに注意してください。これと__del__、オブジェクトとその環境が呼び出されたときに不明な状態になる可能性があるため、使用することはお勧めしません。__del__呼び出されることが完全に保証されているわけではありません-インタープリターは、すべてのオブジェクトを削除せずにさまざまな方法で終了できます。
use del obj1信頼するのは悪い考えのようです。