2 回答
TA贡献1828条经验 获得超13个赞
__del__()
(此处)的文档中有详细说明:
Note
del x
不直接调用x.__del__()
——前者将引用计数减x
一,而后者仅在x
的引用计数达到零时调用。
如果您尝试“解构”一个 Python 对象(并注意我在引号中是如何说的),我建议您使用__exit__()
with语句(此处with
的文档)。
要使用该with
语句,您可以使用以下方法定义一个类:
def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)
一个简单的例子如下:
class Bar:
def __init__(self, *args):
self.stack = list(args)
def __enter__(self):
# Example computation here.
filtered = filter(lambda x: isinstance(x, str), self.stack)
return list(filtered)
def __exit__(self, exc_type, exc_value, traceback):
del self.stack
# Once you leave the 'with' statement, this Bar() object will be deleted for good.
with Bar("Hello", "World!", 1, 2) as stack:
print(stack)
虽然坦率地说,在 Python 中“解构”一个对象几乎是不需要的,并且在大多数情况下,您应该在编程时避免尝试完成垃圾收集器的工作。使用del是一回事,但试图“解构”一个对象是另一回事。
TA贡献1829条经验 获得超7个赞
该__del__方法在对象的引用计数达到 0 时调用,或者在循环引用的情况下被垃圾回收器遍历时调用。例如,以下内容:
class Foo:
def __del__(self):
print('Foo has been deleted!')
foo = Foo()
del foo
将正确调用该__del__方法并打印Foo has been deleted!,因为分配给的对象foo仅被引用一次。现在让我们看一下下面的例子:
class Foo:
def __del__(self):
print('Foo has been deleted!')
foo = Foo()
foo.self = foo
del foo
该__del__方法不会被调用,因为foo.self它会将自己作为人质。只有在被垃圾收集器遍历时才会被删除。例如:
from gc import collect
class Foo:
def __del__(self):
print('Foo has been deleted!')
foo = Foo()
foo.self = foo
del foo
collect()
该__del__方法将被调用,因为我们告诉收集器遍历待处理的对象。不推荐,但您可以通过将阈值设置为 1 来告诉 Python 遍历所有队列。例如:
from gc import set_threshold
set_threshold(1, 1, 1)
class Foo:
def __del__(self):
print('Foo has been deleted!')
foo = Foo()
foo.self = foo
del foo
因此,每次实例化 1 个对象时,收集器都会运行。但同样,不推荐,因为它可能成本高昂并影响代码的性能。
添加回答
举报