似乎对象清理是我在编程期间遇到的一个非常常见的问题。到目前为止,我一直将with语句用作推荐的here
今天我有了另一个想法,这对我来说似乎更优雅(因为它不需要最终用户的with语句)。这个想法是对特定类型的对象使用try-finally修饰器(有一个清理方法)。
只是想知道这种做法有没有什么问题,或者有没有更好的东西。我不喜欢我的许多类需要使用with语句进行初始化,但我也希望确保我的对象被正确地关闭。下面是一个简短的示例。
def cleanme(func):
def _decorator(self, *args, **kwargs):
try:
func(self, *args, **kwargs)
finally:
self._cleanup()
return _decorator
class IObject(object):
def __init__(self):
self.file_name = "some_file.txt"
self._file_object = None
self._cleaned = True
@cleanme
def run(self):
self._connect()
while True:
# do some things over a long period
pass
def _connect(self):
self._file_object = open(self.file_name)
self._cleaned = False
def _cleanup(self):
if not self._cleaned:
self._file_object.close()
self._cleaned = True发布于 2014-07-22 23:21:46
让我在这上面打几个洞。
有一种想法是,你要求你的类有一个cleanup(),它被声明在与run()不同的地方。因此,你把实现和维护它的责任强加给了用户。
__exit__以外的析构函数在Python中非常少见,因此资源获取代码可能会偏离cleanup()代码,从而造成泄漏。
其次,您将file_object设置为实例变量,从而将其作用域从单个函数扩大,这也有些糟糕。
发布于 2014-07-22 23:24:39
我认为,只要您的客户端只使用您的IOObject来做run做的任何事情,并且不想直接调用connect,然后使用打开的file_object执行一些其他操作,那么这种方法是可以的。
上下文管理器让客户端很容易知道他们在哪里获取/清理资源,并且还给了他们灵活性,让他们基本上可以对资源做任何他们想做的事情,因为他们知道一旦离开with块,它就会被清理。使用这种方法就不太清楚了;客户机需要查看代码(或者文档)才能知道run方法将为它们清理,但是如果直接使用connect,则需要调用cleanup来正确清理。
还有一条Python的禅宗法则"Excplicit比Implicit更好“。with语句显式地显示获取和释放资源的客户端。使用装饰器方法就会失去这一点。
https://stackoverflow.com/questions/24891036
复制相似问题