5
class ToBeDeleted:
    def __init__(self, value):
        self.value = val

    # Whatever...

    def __del__(self):
        print self.value

l = [ToBeDeleted(i) for i in range(3)]
del l

これは印刷され2, 1, 0ます。


  • さて、削除された要素の順序は仕様のどこかで定義されていますか、それとも実装固有ですか? (または、基本的なメカニズムを理解していない可能性があります)

  • たとえば、出力は次のようになり0, 1, 2ますか? 要素の削除中に要素のメモリの再割り当てを回避するために、おそらく注文が行われることを認識して2, 1, 0いますが、それでも問題は残ります。

  • del l最後に、ステートメントとステートメントの違いは何del l[:]ですか?

4

3 に答える 3

8

実行del lするとリストへの参照がすべて削除されるため、記号lはなくなります。対照的に、runningdel l[:]はリストの内容を削除し、lを空のリストとして残します。

__del__メソッドは、インスタンスへの最後の参照が破棄されるときに実行されるものです

削除の順序は指定されておらず、実装固有です。を実行するdel lと、リストlとその各要素の参照カウントが 1 ずつ減少することが保証されます。

pypyを使用すると、ガベージ コレクターが実行されるまで何も起こりません。オブジェクトの削除の順序は、GC がオブジェクトにアクセスする順序によって異なります。

cpythonでは、参照のデクリメントが右から左に行われることを観察した OP は正しかった。ここで呼び出すときdel l[:]は、refcounts をデクリメントするために使用されるコードです: http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l700。がdel l呼び出されると、同様のコードを使用して参照カウントを減らします: http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l596

于 2011-11-20T22:04:43.860 に答える
2

他の人はすでに答えています。CPython ソースで見つけたものを追加します。

ファイル内のlist_dealloc関数にはlistobject.c、リスト項目をループして参照カウントを減らす直前に、次のコメントが含まれています。

    /* Do it backwards, for Christian Tismer.
       There's a simple test case where somehow this reduces
       thrashing when a *very* large list is created and
       immediately deleted. */
于 2011-11-20T22:21:26.163 に答える
1
  • 削除順序は実装固有です。
  • 最初のポイントへの答えによると、はい、他の順序で削除する可能性があり(要素が最初、ランダムなど)、再割り当てを回避することはほとんど関係ありません。実装がどのように子を歩かせるかが問題です。おそらく、解放の順序が割り当ての順序を逆にすると、メモリ アロケータはより適切に処理されます。しかし、それは単なる推測です。
  • del ldel l[:]リストからすべての要素を削除するのに対し、変数自体を削除します(したがって、他に何も保持されていない場合はリストも削除します)。試してみてくださいdel l; print l
于 2011-11-20T22:11:00.610 に答える