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

为什么我不';我看不到在python中调用析构函数,python,python-2.7,destructor,Python,Python 2.7,Destructor,我正在开发一个用python编写的API。我使用这篇文章作为对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'

我正在开发一个用python编写的API。我使用这篇文章作为对
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()

我希望在我的屏幕上看到的是,一旦一切都完成了,就会出现以下语句:
关闭与某个设备的连接
。但是由于某种原因,我没有。有人能解释为什么会这样吗

即使所有操作都已完成,对象仍会被引用。如果希望看到这一行出现,请在创建对象后终止程序。Python必须销毁每个对象,因此将运行
\uu del\uu
方法。
但是,正如注释中指出的,Python并不保证调用此方法。由于Python使用垃圾收集器,因此不应该(或者更确切地说,不应该)手动销毁对象。如果要确保调用了
\uuu del\uu
方法,请调用
del
语句。

首先del不保证调用它。这是某些垃圾收集器的“问题”,即:循环引用

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

with open("filename") as f:
     for line in f:
        pass
如果需要更复杂的逻辑,可以使用decorator定义自己的with子句,然后使用enterexit方法创建一个类。您可以在文档中查看更多信息并查看此信息


您还可以通过创建并调用负责正确处理设备(包括正确关闭设备及其gc)的
open()?如果是,请准确说明您如何称呼它。您首先需要创建它的实例并存储在某个变量上。然后它将在退出时自动销毁,并执行del。@RustemK抱歉。我犯了一个错误
A
是指
ApiCfg
。现在修复它。是的,Python实际上并不保证调用
\uu del\uu
<代码>\uuu del\uu
不可靠。在其他Python实现上,它甚至更不可靠,并且标准实现不能保证ref计数机制保持不变。Python不是C++;尝试依赖于<代码>“Y-DELXY<<代码>,就像您依赖C++析构函数是一个坏主意。”USER357112,那么,建议关闭设备连接?<>代码>用/<代码>语句。主要是什么。建议关闭与设备的连接?@ Flash Buy手动关闭它。无论设备是什么,都应该有某种
close
方法。如果异常可能会阻止关闭,请将其放入
finally
块中。或者,如果它支持用作上下文管理器,请使用
with
语句。@flashburn是的,我建议您设计类,使其支持上下文管理。这非常方便使用。@Rightleg那么我如何设计它,使其在删除时设备连接关闭,我无法真正可视化。@flasburn上下文管理的工作方式是:1-使用
语句创建对象(基本
\uu enter\uu
方法);2-创建新范围(即缩进);3-做你的事;4-关闭作用域(即,unindent),该作用域调用
\uuu退出\uu
方法。基本上,
\uuuuuuuuuuuuuuuuuuuu
创建并返回一个对象,
\uuuuuuuuuuuuuuuuuuuuuuuuuu
以干净的方式删除它。无论如何,当您离开上下文范围时,对象不再被引用,因此您不必手动删除它(因为Python)。但是通常,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?令人满意的答案?