【发布时间】:2014-02-13 08:14:00
【问题描述】:
我一直在测试一个受 http://docs.python.org/2/library/contextlib.html 启发的肮脏 hack。 主要思想是将try/finally思想带入类级别,并获得可靠且简单的类析构函数。
class Foo():
def __init__(self):
self.__res_mgr__ = self.__acquire_resources__()
self.__res_mgr__.next()
def __acquire_resources__(self):
try:
# Acquire some resources here
print "Initialize"
self.f = 1
yield
finally:
# Release the resources here
print "Releasing Resources"
self.f = 0
f = Foo()
print "testing resources"
print f.f
但它总是给我:
Initialize
testing resources
1
永远不要“释放资源”。我寄希望于:
从 Python 2.5 版开始,yield 语句现在允许在 try 子句的 try ... finally 构造。如果发电机不是 在最终确定之前恢复(通过达到零引用计数或 通过被垃圾收集),生成器迭代器的 close() 方法 将被调用,允许执行任何未决的 finally 子句。 Source link
但似乎当类成员与类一起被垃圾收集时,它们的引用计数不会减少,因此生成器 close() 并且因此永远不会调用 finally。至于报价的第二部分
“或者被垃圾回收”
我只是不知道为什么这不是真的。有没有机会让这个乌托邦发挥作用? :)
顺便说一句,这适用于模块级别:
def f():
try:
print "ack"
yield
finally:
print "release"
a = f()
a.next()
print "testing"
输出将如我所料:
ack
testing
release
注意:在我的任务中,我无法使用 WITH 管理器,因为我正在释放线程的 end_callback 内的资源(它将不在任何 WITH 中)。所以我想在由于某种原因不会调用回调的情况下获得一个可靠的析构函数
【问题讨论】:
-
不能保证程序结束时剩下的任何东西都会被垃圾回收,也不能保证它们的析构函数会运行。
-
@user2357112,那么为什么这总是在模块级别上有效,而在课堂上却没有呢?
-
任意实施决策。你不应该依赖任何一个版本。
-
与仅仅定义
__del__相比,您希望从这些扭曲中获得什么? -
嗯,它不是,主要是因为它只是
__del__的花哨语法。生成器也是对象,必须通过与其他对象相同的方式完成。
标签: python garbage-collection generator destructor yield