上下文管理器定义了设置/清理功能__enter__和__exit__。太棒了。我想保留一个作为成员变量。当我的类对象超出作用域时,我希望执行此清理。这基本上就是我所理解的C++构造函数/析构函数自动发生的行为。
class Animal(object):
def __init__(self):
self.datafile = open("file.txt") # This has a cleanup function
# I wish I could say something like...
with open("file.txt") as self.datafile: # uh...
def makeSound(self):
sound = self.datafile # I'll be using it later
# Usage...
if True:
animal = Animal()
# file should be cleaned up and closed at this point.发布于 2014-11-22 08:40:09
Python不做C++风格的RAII (“资源获取就是初始化”,意思是你在构造函数中获取的任何东西,你在析构函数中释放)。事实上,除了C++之外,几乎没有其他语言可以实现C++风格的RAII。Python的上下文管理器和with语句是一种不同的方法,可以实现C++对RAII所做的事情,以及大多数其他语言对finally语句、guard语句等所做的事情(当然,Python也有finally )。
你所说的“当我的类对象超出范围时”到底是什么意思?
对象不会超出作用域;引用(或变量,或名称,随您喜欢)会超出作用域。在最后一个引用超出作用域之后的一段时间(对于CPython,这是立即进行的,除非它涉及到引用周期;对于其他实现,通常不会),该对象将被垃圾收集。
如果你想在你的对象被垃圾收集时做一些清理,你可以使用__del__方法。但这很少是你真正想要的。(实际上,有些类有一个__del__方法,只是用来警告用户他们忘记清理了,而不是静默地清理。)
更好的解决方案是使Animal本身成为上下文管理器,这样它就可以管理其他上下文管理器--或者只是显式地管理事物。然后你可以写:
if True:
with Animal() as animal:
# do stuff
# now the file is closed下面是一个例子:
class Animal(object):
def __init__(self):
self.datafile = open("file.txt")
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.datafile.close()
def makeSound(self):
sound = self.datafile # I'll be using it later(就像这样从__exit__的末尾掉下来意味着,在调用self.datafile.close()之后,如果没有异常,我们将成功地什么都不做,或者如果有异常,则重新引发相同的异常。因此,您不需要编写任何明确的代码来实现这一点。)
但通常,如果要将类放入上下文管理器中,还需要添加一个显式的close。就像文件一样。一旦这样做了,就不需要将Animal变成上下文管理器;只需使用closing即可。
发布于 2014-11-22 08:40:19
如果有意义,我会给类一个close函数,然后使用closing上下文管理器:
class MyClass(object):
def __init__(self):
self.resource = acquire_resource()
def close():
release_resource(self.resource)然后像这样使用它:
from contextlib import closing
with closing(MyClass()) as my_object:
# use my_objecthttps://stackoverflow.com/questions/27072664
复制相似问题