`__del__` 和 `__delete__` 有什么区别?

Too*_*one 6 python destructor destruction python-3.x

__del__假设有人不知道和之间有什么区别__delete__?写一个解释。

Too*_*one -2

__del__当您删除对象时调用,__delete__有时在删除对象的属性时调用。

\n\n
del x.my_num    # __delete__\ndel x           # __del__            \n
Run Code Online (Sandbox Code Playgroud)\n\n

关于__del__:

\n\n

以下代码显示何时__del__被调用:

\n\n
class MyClass:\n    def __init__(self):\n        file = open("really_cool_file.txt", "w+")\n        self._f = file\n\n    def __del__(self):\n        print("closing any open files ")\n        self._f.close()\n\nmy_instance = MyClass()\ndel my_instance\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果 my_instance是指向数据的最后一个标签,则del my_instance调用MyClass.__del__(my_instance)

\n\n

从技术上讲,del my_instance仅删除标签my_instance。想象一下聚会上的人们都戴着名牌。有时一个人同时贴有 6 或 7 个名字标签,而其他时候则只有一个。Python 会将任何未佩戴至少一个名牌的人踢出聚会。MyClass.__del__(my_instance)当从数据中删除最后一个姓名标签/标签时,会调用该函数。

\n\n

上面的代码显示了我们何时确保关闭打开的文件的示例。另一个例子可能是计算给定类的活动实例的数量:

\n\n
class Klass:\n    count = 0\n    # `count` belongs to the class\n    # instances do not each get their own copy of `count`\n    def __init__(self):\n        type(self).count += 1\n        self.instance_var = "I belong to instances"\n    def __del__(self):\n        type(self).count -= 1\nobj = Klass()\nprint(obj.count)\n
Run Code Online (Sandbox Code Playgroud)\n\n

关于__delete__

\n\n

与 不同__del____delete__与描述符有关。\n下面的代码描述了obj.my_var或 的行为getattr(obj, \xe2\x80\x9cmy_var\xe2\x80\x9d)

\n\n

class Klaus:\n def getattribute (self, attrname):\n try:\n attribute = 来自实例 Klaus 的 attrname\n except AttributeError:\n attribute = 来自类 Klaus 的 attrname

\n\n
    # Begin code for handling "descriptors"\n    if hasattr(attribute, \'__get__\'):\n        attr = attribute.__get__(self, Klaus)\n    # End code for handling "descriptors"\n\n    return attribute\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果my_var是描述符,则以下两行代码等效:

\n\n
x = obj.my_var\nx = Klass.my_var.__get__(obj, "my_var")\n
Run Code Online (Sandbox Code Playgroud)\n\n

就像__getattribute__检查属性是否有__get__方法一样,__delattr__将检查属性__delete__是否有方法。

\n\n
def __delattr__(self, name):\n    attribute = getattr(self, name)\n    if hasattr(attribute, "__delete__"):\n       attribute.__delete__(self)\n    else:\n       del self.__dict__[name]\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以__delete__通过查看以下代码来了解何时被调用:

\n\n
class desc:\n    def __delete__(descriptor, instance_of_Klaus):\n        print("attribute was deleted")\n\nclass Klaus:\n    d = desc()\n    def __init__(self):\n        pass\n\nmy_instance = Klaus()\ndel my_instance.d\n
Run Code Online (Sandbox Code Playgroud)\n\n

处理描述符时,以下代码行都是等效的:

\n\n
del my_instance.d\ndelattr(my_instance, "d")\nKlaus.d.__delete__(my_instance)\n
Run Code Online (Sandbox Code Playgroud)\n

  • 所以,请注意,“del”不会删除对象,它会删除*名称*。Python 无法显式控制对象的分配/释放。我认为这是一个很好的问题,也可能是一个很好的答案,但它的基本部分是错误的,因此具有误导性。IOW:“`del my_instance` 与 `MyClass.__del__(my_instance)` 相同”是**绝对**错误的。 (5认同)
  • 当你执行“del Something”时,不会调用“del”。当对象的引用计数达到零时(或者更一般地,当引用对象被垃圾收集时),它被调用。这实际上是不同Python实现之间不兼容的根源 (2认同)