首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Try-finally修饰器清理python对象

Try-finally修饰器清理python对象
EN

Stack Overflow用户
提问于 2014-07-22 23:07:28
回答 2查看 1.9K关注 0票数 5

似乎对象清理是我在编程期间遇到的一个非常常见的问题。到目前为止,我一直将with语句用作推荐的here

今天我有了另一个想法,这对我来说似乎更优雅(因为它不需要最终用户的with语句)。这个想法是对特定类型的对象使用try-finally修饰器(有一个清理方法)。

只是想知道这种做法有没有什么问题,或者有没有更好的东西。我不喜欢我的许多类需要使用with语句进行初始化,但我也希望确保我的对象被正确地关闭。下面是一个简短的示例。

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2014-07-22 23:21:46

让我在这上面打几个洞。

有一种想法是,你要求你的类有一个cleanup(),它被声明在与run()不同的地方。因此,你把实现和维护它的责任强加给了用户。

__exit__以外的析构函数在Python中非常少见,因此资源获取代码可能会偏离cleanup()代码,从而造成泄漏。

其次,您将file_object设置为实例变量,从而将其作用域从单个函数扩大,这也有些糟糕。

票数 3
EN

Stack Overflow用户

发布于 2014-07-22 23:24:39

我认为,只要您的客户端只使用您的IOObject来做run做的任何事情,并且不想直接调用connect,然后使用打开的file_object执行一些其他操作,那么这种方法是可以的。

上下文管理器让客户端很容易知道他们在哪里获取/清理资源,并且还给了他们灵活性,让他们基本上可以对资源做任何他们想做的事情,因为他们知道一旦离开with块,它就会被清理。使用这种方法就不太清楚了;客户机需要查看代码(或者文档)才能知道run方法将为它们清理,但是如果直接使用connect,则需要调用cleanup来正确清理。

还有一条Python的禅宗法则"Excplicit比Implicit更好“。with语句显式地显示获取和释放资源的客户端。使用装饰器方法就会失去这一点。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24891036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档