小编Cle*_*aff的帖子

对于Python中的gc,动态创建的类总是"无法访问"吗?

我有一个关于Python中的垃圾收集的问题.在阅读了一些有关为什么人们可能更喜欢运行带有禁用垃圾收集*的Python程序的有见地的文章后,我决定搜索并删除代码中的所有循环引用,以允许通过单独的ref-count来销毁对象.

为了找到现有的循环引用,我在我的unittest案例的tearDown方法中调用了gc.collect(),并在返回值> 0时打印出警告.通过重构或使用弱引用可以轻松解决发现的大多数问题.

过了一会儿,我遇到了一个相当奇怪的问题,最好用代码表达:

import gc
gc.disable()

def bar():
    class Foo( object ):
        pass

bar()
print( gc.collect() ) # prints 6
Run Code Online (Sandbox Code Playgroud)

删除对bar()的调用时,gc.collect()会按预期返回0.

看起来即使Foo是在函数栏的范围内创建的并且永远不会返回到外部,它仍然会使垃圾收集器找到无法访问的对象.

将Foo移到bar的范围之外时,一切正常.但是,该解决方案不适用于我在受影响的代码中尝试解决的问题(动态创建ctypes.Structures用于序列化).

以下两种方法也不起作用:

import gc
gc.disable()

def bar():
    type( "Foo", ( object, ), {} )

bar()
print( gc.collect() ) # prints 6 again
Run Code Online (Sandbox Code Playgroud)

甚至非常'聪明':

import gc
gc.disable()

import weakref

def bar():
    weakref.ref( type( "Foo", ( object, ), {} ) )

bar()
print( gc.collect() ) # still prints 6
Run Code Online (Sandbox Code Playgroud)

最重要的是,这是一个实际工作的例子......但仅限于Python2:

import gc
gc.disable()

def bar():
    class Foo(): # not …
Run Code Online (Sandbox Code Playgroud)

python garbage-collection

6
推荐指数
1
解决办法
550
查看次数

标签 统计

garbage-collection ×1

python ×1