のPythonドキュメントでは、オブジェクトの参照カウントがゼロに減少したときに__del__
オブジェクトのメソッドを呼び出すことができると説明されています。__del__
それは常にすぐに(つまり同期的に)呼び出されますか?または、__del__
メソッドが「将来のある時点で」呼び出される可能性はありますか?
さらに、この質問への答えは一般的にPythonに当てはまりますか?それとも、言語の実装にある程度の寛容さが与えられていますか?(私はCPythonを使用しています。)
この質問では、次のことを想定しています。
- 問題のオブジェクトはから継承し
object
ます。 - 問題のオブジェクトにはカスタム
__del__
実装があります。 - オブジェクトのカスタム
__del__
実装は、オブジェクトへの新しい参照を作成しません。 - 問題のオブジェクトは、参照サイクルの一部ではありません。
- 通訳はシャットダウン中です。
私の知る限り、このトピックについては多くの混乱があるようです。不必要な議論を回避するために、受け入れられない答えの例をいくつか挙げましょう。
- 「使用しないでください
__del__
!紛らわしいです!」 - 「使用しないでください
__del__
!「pythonic」ではありません。」 - 「使用しないでください
__del__
。代わりにコンテキストマネージャーを使用してください。」 - 信頼できる情報源を引用せずに、何が保証されているか、何が保証されていないかについて主張する答え。(他のSOの回答を自由に引用してください。ただし、それらを唯一のソースとして信頼しないでください。この場合の「信頼できる」とは、ドキュメント、信頼できる人物、またはCPythonソース自体からの何かを意味します。)
この質問を例で言い換えると、次のコードを検討してください。
class C(object):
def __init__(self, i):
self.i = i
def __del__(self):
print "C.__del__:", self.i
print "Creating list"
l = [C(0), C(1), C(2)]
print "Popping item 1"
l.pop(1)
print "Clearing list"
l = []
print "Exiting..."
これにより、次の出力が生成されます。
$ python test_del.py
Creating list
Popping item 1
C.__del__: 1
Clearing list
C.__del__: 2
C.__del__: 0
Exiting...
この例では、が同期的__del__
に呼び出されていることに注意してください。その動作は言語によって保証されていますか?(上記の前提条件に注意してください。)