【问题标题】:__del__() with args in additional to self__del__() 除了 self 之外还有 args
【发布时间】:2021-04-11 12:03:14
【问题描述】:

我有一个 Python 程序如下:

class a:
    def __init__(self,n):
        self.n=n
    def __del__(self,n):
        print('dest',self.n,n)
def b():
    d=a('d')
    c=a('c')
    d.__del__(8)
    
b()

在这里,我在__del__() 中给出了一个参数n,只是为了清除我的疑问。它的输出:

$ python des.py 
dest d 8
Exception ignored in: <function a.__del__ at 0xb799b074>
TypeError: __del__() missing 1 required positional argument: 'n'
Exception ignored in: <function a.__del__ at 0xb799b074>
TypeError: __del__() missing 1 required positional argument: 'n'

在像 C++ 这样的经典编程语言中,我们不能为析构函数提供参数。要知道它是否也适用于 python,我已经执行了这个程序。为什么解释器允许将参数n 作为析构函数的参数给出?那我该如何为n 指定值呢?尝试为__del__() 提供一个论据,结果很好。但是没有它我怎么能指定n的值呢?

【问题讨论】:

  • 为什么会防止呢? Python 是动态类型的,你可以根据自己的喜好定义这些方法,但如果你弄错了,可能(如本例)在运行时看到错误。
  • 基本上,__del__ 不能有额外的参数,尽管语言并没有严格执行这条规则;带有额外参数的__del__ 方法仍然可以直接调用,只是当您使用del 关键字时,它不能起到正确的__del__ 方法的作用。

标签: python destructor


【解决方案1】:

你不能。 __del__ 等预定义的 dunder 方法(带有前后双下划线的方法)具有固定签名。

如果你用另一个签名定义它们,那么当python使用非dunder接口(@98​​7654324@,len,...)调用它们时,参数的数量是错误的,它会失败。

要将n 传递给del,您必须将其定义为对象成员。

【讨论】:

【解决方案2】:

当不再有对 Python 对象的引用(对象标记)时,Python 对象将成为垃圾回收的候选对象,因此您不需要创建这样的析构函数。

如果要为方法添加可选参数,通常将它们设置为None 或空元组()

    def other_del(self, x=None):
        ...

【讨论】:

    【解决方案3】:

    您可以定义带有参数的__del__ 方法,如您所展示的。如果您自己调用该方法,您可以传入一个值,就像您可以使用任何其他方法一样。但是当解释器自己调用__del__时,它不会传递任何东西,并且会引发异常。

    但是,因为__del__ 方法经常在不稳定的情况下被调用,例如当解释器关闭时,如果引发异常,Python 不会停止一切。相反,它只是打印出它忽略了异常并继续做它已经在做的事情。这就是为什么当您的 dc 对象被清理时,您会看到两条“已忽略异常”消息。

    我不清楚你实际上希望你的 __del__ 方法与你传入的 n 值做什么。你的例子是一个微不足道的例子,通常没有什么有用的可以做那里。事实上,为一个类编写一个__del__ 方法很少是一个好主意。有更好的资源分配方法,例如上下文管理器协议(使用__enter____exit__ 方法)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-04
      • 1970-01-01
      • 2015-12-08
      • 1970-01-01
      • 2023-02-09
      • 1970-01-01
      • 2014-01-31
      • 2011-05-12
      相关资源
      最近更新 更多