关闭资源的方法是使用上下文管理器,也称为
with
语句:
class Foo(object):
def __init__(self):
self.bar = None
def __enter__(self):
if self.bar != 'open':
print 'opening the bar'
self.bar = 'open'
return self
def close(self):
if self.bar != 'closed':
print 'closing the bar'
self.bar = 'close'
def __exit__(self, *err):
self.close()
if __name__ == '__main__':
with Foo() as foo:
print foo, foo.bar
输出:
opening the bar
<__main__.Foo object at 0x17079d0> open
closing the bar
2)当Python对象的引用计数为0时,它们将被删除。在您的示例中,del foo
删除了最后一个引用,因此立即调用了__del__
。垃圾收集器与此无关。
class Foo(object):
def __del__(self):
print "deling", self
if __name__ == '__main__':
import gc
gc.disable()
f = Foo()
print "before"
del f
print "after"
输出:
before
deling <__main__.Foo object at 0xc49690>
after
< p>
gc
与删除您和大多数其他对象无关。它的作用是在简单引用计数由于自我引用或循环引用而无法工作时进行清理:
class Foo(object):
def __init__(self, other=None):
self.link = other
if other is not None:
other.link = self
def __del__(self):
print "deling", self
if __name__ == '__main__':
import gc
gc.disable()
f = Foo(Foo())
print "before"
del f
print "after"
gc.collect()
print gc.garbage
print "after gc"
del gc.garbage[0].link, gc.garbage[:]
print "done"
输出:
before
after
[<__main__.Foo object at 0x22ed8d0>, <__main__.Foo object at 0x22ed950>]
after gc
deling <__main__.Foo object at 0x22ed950>
deling <__main__.Foo object at 0x22ed8d0>
done
3) 让我们看一下:
class Foo(object):
def __init__(self):
raise Exception
def __del__(self):
print "deling", self
if __name__ == '__main__':
f = Foo()
提供:
Traceback (most recent call last):
File "asd.py", line 10, in <module>
f = Foo()
File "asd.py", line 4, in __init__
raise Exception
Exception
deling <__main__.Foo object at 0xa3a910>
对象是通过__new__
创建的,然后作为self
传递给__init__
。在__init__
中发生异常后,该对象通常不会有名称(即f =
部分不会运行),因此它们的引用计数为0。这意味着对象将被正常删除并调用__del__
。
with
语句。 非常好的提示。以前不知道with
可以用来为任何对象限定作用域。 - Lelouch Lamperouge