- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到了 Python3.2 的问题。如果一个类装饰了父类的一个函数并且也有一个析构函数,那么该类的实例永远不会被垃圾回收。
下面是一些说明问题的示例代码:
def super_simple_decorator(func):
def f(*args, **kwds):
return func(*args, **kwds)
return f
class Parent():
def foo(self):
pass
class Child(Parent):
def __del__(self):
print('In Child.__del__')
def __init__(self):
self.foo = super_simple_decorator(self.foo)
x = Child()
del x
import gc
_ = gc.collect()
print(gc.garbage)
如果您愿意,您也可以在运行时在装饰器中进行猴子修补并看到相同的东西:
class Garbage():
def foo(self):
pass
def __del__(self):
print('In Garbage.__del__')
g=Garbage()
g.foo = super_simple_decorator(g.foo)
del g
在每种情况下,都有未收集的垃圾,大概是因为装饰方法中存在对 self
的绑定(bind)引用。
目前升级到 Python3.4 对我来说并不是一个真正的选择,所以我正在寻找一种方法让像这样的对象得到垃圾收集。
最佳答案
导致这个问题的不是装饰器。事实上,您在它们绑定(bind)的实例上存储了一个方法。装饰器在这里只是手段,并不是真正的原因。
方法持有对 __self__
中实例的引用,然后您通过将方法存储在带有装饰器对象的闭包中创建循环引用,返回到 self.foo
。 不要那样做。 Python 3.3 及之前的版本不会对具有 __del__
方法的对象的循环引用进行垃圾回收。
解包方法并存储原始函数:
self.foo = super_simple_decorator(self.foo.__func__)
foo
将不再被绑定(bind),但是,方法仅在查找类而不是实例时才被绑定(bind)。
或者在类级别实际应用装饰器:
class Child(Parent):
def __del__(self):
print('In Child.__del__')
foo = super_simple_decorator(Parent.foo)
如果两者都不是一个选项,则使用弱引用来跟踪实例,而不是引用方法,然后根据需要重新绑定(bind):
import weakref
def super_simple_decorator(method):
instance = weakref.ref(method.__self__)
func = method.__func__
def f(*args, **kwds):
self = instance() # can return None
return func(self, *args, **kwds)
return f
关于具有修饰方法和 __del__ 定义的 Python 类不会被垃圾收集 : how do I uncouple the decorated method?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27043599/
耦合策略和非耦合策略有什么区别? 谢谢回答。 最佳答案 当策略类知道上下文时,或者当客户端知道策略具体类时,策略是耦合的。 我们可以阅读 here (有一些小的修改): Usually each st
我遇到了 Python3.2 的问题。如果一个类装饰了父类的一个函数并且也有一个析构函数,那么该类的实例永远不会被垃圾回收。 下面是一些说明问题的示例代码: def super_simple_deco
我有以下模型和关联: SuccessCriterion has_many :requirements has_many :findings, through: :requirements Re
我是一名优秀的程序员,十分优秀!