如何正确清理 Python 对象?

2024-01-20

class Package:
    def __init__(self):
        self.files = []

    # ...

    def __del__(self):
        for file in self.files:
            os.unlink(file)

__del__(self)上面失败并出现 AttributeError 异常。我明白Python 不保证 http://docs.python.org/reference/datamodel.html#customization存在“全局变量”(在此上下文中的成员数据?)__del__()被调用。如果是这种情况并且这就是异常的原因,我如何确保对象正确销毁?


我建议使用Pythonwith用于管理需要清理的资源的语句。使用显式的问题close()声明是你必须担心人们根本忘记调用它或者忘记将它放在一个finally阻止发生异常时防止资源泄漏。

要使用with语句,使用以下方法创建一个类:

def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)

在上面的示例中,您将使用

class Package:
    def __init__(self):
        self.files = []

    def __enter__(self):
        return self

    # ...

    def __exit__(self, exc_type, exc_value, traceback):
        for file in self.files:
            os.unlink(file)

然后,当有人想要使用您的课程时,他们会执行以下操作:

with Package() as package_obj:
    # use package_obj

变量 package_obj 将是 Package 类型的实例(它是由__enter__方法)。它是__exit__无论是否发生异常,都会自动调用方法。

您甚至可以进一步采用这种方法。在上面的示例中,有人仍然可以使用其构造函数实例化 Package,而不使用with条款。你不希望这种事发生。您可以通过创建一个 PackageResource 类来解决此问题,该类定义了__enter__ and __exit__方法。然后,Package 类将严格定义在__enter__方法并返回。这样,调用者永远无法在不使用with陈述:

class PackageResource:
    def __enter__(self):
        class Package:
            ...
        self.package_obj = Package()
        return self.package_obj

    def __exit__(self, exc_type, exc_value, traceback):
        self.package_obj.cleanup()

您可以按如下方式使用它:

with PackageResource() as package_obj:
    # use package_obj
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何正确清理 Python 对象? 的相关文章

随机推荐