为什么我看不到在python中调用析构函数

时间:2016-11-09 02:42:41

标签: python python-2.7 destructor

我正在研究用python编写的API。我正在使用this文章作为python析构函数的帮助。

# api.py
class ApiCfg(object):
    def __init__(self, ...):
        # open a connection to a device
        some_device_open()

    def __del__(self):
        print 'Close a connection to some_device'
        # close a connection to a device
        some_device_close()

# Some code
...
api_cfg = ApiCfg()

# myfile.py
from api import *

# Do some stuff
api.run()

我期待在屏幕上看到的内容,一切都完成之后的声明如下:Close connection to some device。但出于某种原因,我没有。有人可以解释为什么会这样吗?

2 个答案:

答案 0 :(得分:1)

首先, del 并不保证会被调用。对于某些垃圾收集器来说,这是一个“问题”,即:循环引用。

在您的特定情况下,我看到在初始阶段ApiConfig.__init__您打开了与某个设备的连接。这意味着您可能会增加对象上的引用计数器(反之亦然)。通常当用户处理设备(文件,套接字,管道)时,他应该自己管理打开/关闭它,因为在其对象的引用计数器等于0之前,不会调用 del 。这是为什么我们通常使用with子句来包装正确管理设备生命周期的块的执行。例如:

with open("filename") as f:
     for line in f:
        pass

您可以使用contextlib.contextmanager装饰器定义自己的with子句,或者如果您需要更复杂的逻辑,则使用输入退出方法创建一个类。您可以在doc中查看更多内容并查看此article

此外,您可以通过创建然后调用负责正确设备处理的open()close()方法(包括正确关闭设备及其gc)来以更直接的方式执行此操作。< / p>

答案 1 :(得分:0)

即使已完成所有操作,仍会引用该对象。如果要查看此行,请在创建对象后终止程序。 Python必须破坏每个对象,因此将运行__del__方法。

但是,正如评论中指出的那样,Python并不保证会调用此方法。由于Python使用垃圾收集器,因此不应该(或者更确切地说,不期望)手动破坏对象。如果您想确保调用__del__方法,请调用del语句。