我正在研究用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
。但出于某种原因,我没有。有人可以解释为什么会这样吗?
答案 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
语句。