9

一部のパーツがまだ参照されている場合、Pythonガベージコレクターは複合オブジェクトをクリーンアップしますか

例えば

def foo():
    A = [ [1, 3, 5, 7], [2, 4, 6, 8]]
    return A[1]
B = foo()

A[0]ガベージコレクションされますか?

コードで同じことを確認する方法はありますか?

4

2 に答える 2

15

listAとネストされた list を参照するものはA[0]ないため、はい、メモリから削除されます。

によって参照される入れ子になったリスト オブジェクトA[1]には、元のコンテナーへの接続がありません。

これを行うのはガベージ コレクターではないことに注意してください。GC は循環参照の解除のみを扱います。この単純なケースは、参照カウントによって完全に処理されます。

戻った瞬間foo()、ローカル名前空間がクリアされます。つまりA、リスト オブジェクトの参照カウントが 0 になることを意味します。これにより、そのリスト オブジェクトがクリアされます。これは、含まれているリストの参照カウントも 1 つ減少することを意味します。A[0]つまり、カウントも 0 になり、クリアされます。

によって参照されるリスト オブジェクトについてはA[1]、それへの参照Bがあるため、カウントは 1 のままで、「生きている」ままです。

listコードで同じことを確認するには、__del__メソッドで のサブクラスを使用して、オブジェクトがいつ削除されるかを知らせます。

>>> class DelList(list):
...     def __del__(self):
...         print 'Deleted {}'.format(self)
... 
>>> def foo():
...     A = DelList([DelList([1, 3, 5, 7]), DelList([2, 4, 6, 8])])
...     return A[1]
... 
>>> B = foo()
Deleted [[1, 3, 5, 7], [2, 4, 6, 8]]
Deleted [1, 3, 5, 7]
>>> del B
Deleted [2, 4, 6, 8]

これはすべて CPython (リファレンス Python 実装) に固有のものです。他の実装では、オブジェクトの有効期間を異なる方法で処理する場合があります (たとえば、スイープでオブジェクトを破棄するためにガベージ コレクターを使用しますA) A[0]。GC は、おそらく別の時点ではあるが、他の実装でもそれらを収集します。

于 2014-02-27T13:21:11.893 に答える
1

Martijn は、それA[0]が収集されると説明しました。コードでそれを観察する方法は次のとおりです。

class Bye(object):
   def __del__(self):
      """A special method, called when the object is destroyed."""
      print 'bye'

def foo():
    A = [Bye(), [1,2]]
    return A[1]

foo()

版画:

bye
[1, 2]
于 2014-02-27T13:29:27.160 に答える