回答:
__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
信頼するのは悪い考えのようです。