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

对于Python中的gc,动态创建的类总是“无法访问”吗?,第1张

概述我有一个关于 Python中的垃圾收集的问题.在阅读了一些有关为什么人们可能更喜欢运行带有禁用垃圾收集*的Python程序的有见地的文章后,我决定搜索并删除代码中的所有循环引用,以允许通过单独的ref-count来销毁对象. 为了找到现有的循环引用,我在我的unittest案例的tearDown方法中调用了gc.collect(),并在返回值> 0时打印出警告.通过重构或使用弱引用可以轻松解决发现 我有一个关于 Python中的垃圾收集的问题.在阅读了一些有关为什么人们可能更喜欢运行带有禁用垃圾收集*的Python程序的有见地的文章后,我决定搜索并删除代码中的所有循环引用,以允许通过单独的ref-count来销毁对象.

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

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

import gcgc.disable()def bar():    class Foo( object ):        passbar()print( gc.collect() ) # prints 6

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

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

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

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

import gcgc.disable()def bar():    type( "Foo",( object,),{} )bar()print( gc.collect() ) # prints 6 again

甚至非常’聪明’:

import gcgc.disable()import weakrefdef bar():    weakref.ref( type( "Foo",{} ) )bar()print( gc.collect() ) # still prints 6

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

import gcgc.disable()def bar():    class Foo(): # not subclassing object        passbar()print( gc.collect() ) # prints 0 - finally?

然而,上面的代码再次在python3中打印出“6” – 我怀疑,因为所有用户定义的类都是python3中的新式类.

那么,我是否坚持Python2,python3中奇怪的“无法访问的对象”,或者我是否必须通过手动垃圾收集来跟进每次调用bar?

*(关于使用gc.disable()运行Python的文章)

http://pydev.blogspot.de/2014/03/should-python-garbage-collector-be.html
http://dsvensson.wordpress.com/2010/07/23/the-garbage-garbage-collector-of-python/

请参阅roippi的答案,了解为何上述行为符合预期.

但是为了将来参考,这里有一个小的解决方法,可以解决这个特殊的问题.不是说禁用gc对任何人来说都是正确的,但如果你觉得这对你来说是正确的,那就是我这样做的:

import gcgc.disable()def requiresGC( func ):    def func_wrapper( *args,**kwargs ):        result = func( *args,**kwargs )        gc.collect()        return result    return func_wrapper@requiresGCdef bar():    class Foo( object ):        passbar()print( gc.collect() ) # prints 0

但请注意,如果bar()是定期调用的函数,则此装饰器将导致显着减速.然而,在我的情况下(序列化),情况并非如此,并且将gc开销包含在一些特定函数中似乎是一种合理的折衷方案.

感谢所有花时间快速回答的人! 总结

以上是内存溢出为你收集整理的对于Python中的gc,动态创建的类总是“无法访问”吗?全部内容,希望文章能够帮你解决对于Python中的gc,动态创建的类总是“无法访问”吗?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1205018.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存