相关疑难解决方法(0)

如何正确清理Python对象?

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

    # ...

    def __del__(self):
        for file in self.files:
            os.unlink(file)
Run Code Online (Sandbox Code Playgroud)

__del__(self)上面因AttributeError异常而失败.我理解Python__del__()调用时不保证存在"全局变量"(在此上下文中的成员数据?).如果是这种情况并且这是异常的原因,我该如何确保对象正确破坏?

python destructor

436
推荐指数
10
解决办法
40万
查看次数

__del__的用例

在python 3中编写自定义__del__方法或依赖stdlib 1中的一个用例是什么?也就是说,在什么情况下它是相当安全的,并且可以做一些没有它的事情很难做到的事情?

出于很多好的理由(1 2 3 4 5 6),通常的建议是避免__del__使用上下文管理器或手动执行清理:

  1. __del__如果对象在intrepreter出口2上处于活动状态,则不保证会被调用.
  2. 在点1期望对象可以被破坏时,引用计数实际上可以是非零的(例如,引用可以通过由调用函数保持的回溯帧而存活).这使得破坏时间远比仅仅gc暗示的不可预测性更不确定.
  3. 垃圾收集器如果包含多个对象,则无法摆脱循环 __del__
  4. 内部代码__del__必须仔细编写:
    • 设置的对象属性__init__可能不存在,因为__init__可能引发了异常;
    • 异常被忽略(仅打印到stderr);
    • 全局变量可能不再可用.

更新:

PEP 442在行为上做出了重大改进__del__.虽然我的第1-4点仍然有效?


更新2:

一些顶级的python库包含__del__在后PEP 442 python(即python 3.4+)中的使用.我想我的观点3在PEP 442之后不再有效,其他点被接受为对象终结的不可避免的复杂性.


1我将问题从编写自定义__del__方法扩展到包括依赖于__del__stdlib.

2似乎__del__总是在更新版本的Cpython中调用解释器退出(有没有人有反例?).然而,对于__del__可用性的目的并不重要:文档明确地不提供对此行为的保证,因此不能依赖它(它可能在将来的版本中发生变化,在非CPython解释器中可能会有所不同) .

python destructor python-3.x

14
推荐指数
2
解决办法
896
查看次数

在 __del__ 中关闭类似连接的对象的 Pythonic 方法

我正在研究一个实现上下文管理器的类似连接的对象。强烈鼓励写这样的东西:

with MyConnection() as con:
    # do stuff
Run Code Online (Sandbox Code Playgroud)

当然也可以这样做:

con = MyConnection()
# do stuff
con.close()
Run Code Online (Sandbox Code Playgroud)

但未能关闭连接是相当有问题的。所以关闭__del__()似乎是一个好主意:

def __del__(self):
    self.close()
Run Code Online (Sandbox Code Playgroud)

这看起来很不错,但有时会导致错误:

Exception ignored in: [...]
Traceback (most recent call last):
  File "...", line xxx, in __del__()
TypeError: 'NoneType' object is not callable
Run Code Online (Sandbox Code Playgroud)

看起来好像有时 close 方法已经被销毁,当__del__()被调用时。

所以我正在寻找一种很好的方法来鼓励 python 在破坏时正确关闭连接。如果可能的话,我想,以避免代码重复close()__del__()

python

4
推荐指数
1
解决办法
4455
查看次数

标签 统计

python ×3

destructor ×2

python-3.x ×1