6

以下の動作がわかりません。

  • locals()新しい参照はどのように発生しますか?
  • gc.collect で削除されないのはなぜですか? locals()私はどこにも結果を割り当てませんでした。

バツ

import gc

from sys import getrefcount

def trivial(x): return x

def demo(x):
    print getrefcount(x)
    x = trivial(x)
    print getrefcount(x)
    locals()
    print getrefcount(x)
    gc.collect()
    print getrefcount(x)


demo(object())

出力は次のとおりです。

$ python demo.py 
3
3
4
4
4

3 に答える 3

2

デモコードにいくつかのプリントを追加しました:

#! /usr/bin/python

import gc

from sys import getrefcount

def trivial(x): return x

def demo(x):
    print getrefcount(x)
    x = trivial(x)
    print getrefcount(x)
    print id(locals())
    print getrefcount(x)
    print gc.collect(), "collected"
    print id(locals())
    print getrefcount(x)


demo(object())

出力は(私のマシン上で)次のとおりです。

3
3
12168320
4
0 collected
12168320
4

locals() は、実際には x の ref を含む dict を作成するため、ref inc. gc.collect() は locals dict を収集しません。ID を出力することで確認できます。これは同じオブジェクトが 2 回返されたものであり、このフレーム用に何らかの方法でメモ化されているため、収集されません。

于 2014-03-08T00:30:11.177 に答える
-1

これは、locals() が実際の辞書を作成し、その中に x を配置するためです。したがって、x の参照カウントが増加します。この辞書はおそらくキャッシュされます。

だから私は2行を追加してコードを変更しました

import gc

from sys import getrefcount

def trivial(x): return x

def demo(x):
   print getrefcount(x)
   x = trivial(x)
   print getrefcount(x)
   print "Before Locals ",  gc.get_referrers(x)
   locals()
   print "After Locals ",  gc.get_referrers(x)
   print getrefcount(x)
   gc.collect()
   print getrefcount(x)
   print "After garbage collect", gc.get_referrers(x)

demo(object())   

ここにコードの出力があります

3
3
Before Locals  [<frame object at 0x1f1ee30>]
After Locals  [<frame object at 0x1f1ee30>, {'x': <object object at 0x7f323f56a0c0>}]
4
4
After garbage collect [<frame object at 0x1f1ee30>, {'x': <object object at 0x7f323f56a0c0>}]

locals() への将来の呼び出しのために、ガベージ コレクションの後でも dict 値をキャッシュしているようです。

于 2014-03-08T00:16:29.160 に答える