`__del__` 和 `__delete__` 有什么区别? [重复]

问题描述 投票:0回答:2

假设有人不知道

__del__
__delete__
之间有什么区别?写个解释吧。

python python-3.x destructor destruction
2个回答
2
投票

 object.__del__(self)

当实例即将被销毁时调用。这也称为终结器或(不正确的)析构器。如果基类具有

__del__()
方法,则派生类的
__del__()
方法(如果有)必须显式调用它,以确保正确删除实例的基类部分。

这意味着在

my_object.__del__
的引用计数降至零后,CPython 的垃圾收集器将调用
my_object

 object.__delete__(self, instance)

调用以删除所有者类的实例

instance
上的属性。

__delete__
dunder 方法与 python 的 descriptors 概念相关;描述符是“定义方法
__get__()
__set__()
__delete__()
的任何对象”。描述符可用于实现属性查找/分配/删除的自定义行为(分别通过
__get__
/
__set__
/
__delete__
)。

另请参阅:

  • del
    语句
    :“删除名称会从本地或全局名称空间中删除该名称的绑定...属性引用、订阅和切片的删除将传递给所涉及的主要对象...”
  • delattr
    内置功能。从文档中,“只要对象允许,该函数就会删除指定的属性。例如,
    delattr(x, 'foobar')
    相当于
    del x.foobar
    。”
  • 尝试删除属性时会调用
  • object.__delattr__(self, name)
    。根据文档,“只有当
    del obj.name
    对对象有意义时才应该实现。”因此,使用方法
    MyClass.__delattr__
    定义用户类可以在以下情况下启用自定义行为:语句
    del my_object.an_attr
    被调用,或者(等效地)当
    delattr(my_object, 'an_attr')
    被调用时。
  • object.__delitem__(self, key)
    是“调用以实现
    self[key]
    的删除”。因此,使用方法
    MyClass.__delitem__
    定义用户类可以在以下情况下启用自定义行为:调用语句
    del my_object[a_key]

-3
投票
删除对象时会调用

__del__
,删除对象的属性时有时会调用
__delete__

del x.my_num    # __delete__
del x           # __del__            

关于
__del__:

以下代码显示何时调用

__del__

class MyClass:
    def __init__(self):
        file = open("really_cool_file.txt", "w+")
        self._f = file

    def __del__(self):
        print("closing any open files ")
        self._f.close()

my_instance = MyClass()
del my_instance

如果

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

从技术上讲,

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

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

class Klass:
    count = 0
    # `count` belongs to the class
    # instances do not each get their own copy of `count`
    def __init__(self):
        type(self).count += 1
        self.instance_var = "I belong to instances"
    def __del__(self):
        type(self).count -= 1
obj = Klass()
print(obj.count)

关于
__delete__

__del__
不同,
__delete__
与描述符有关。 下面的代码描述了
obj.my_var
getattr(obj, “my_var”)

的行为

克劳斯类: def getattribute(self, attrname): 尝试: attribute = 来自实例 Klaus 的 attrname 除了属性错误: attribute = 来自 Klaus 类的 attrname

    # Begin code for handling "descriptors"
    if hasattr(attribute, '__get__'):
        attr = attribute.__get__(self, Klaus)
    # End code for handling "descriptors"

    return attribute

如果

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

x = obj.my_var
x = Klass.my_var.__get__(obj, "my_var")

就像

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

def __delattr__(self, name):
    attribute = getattr(self, name)
    if hasattr(attribute, "__delete__"):
       attribute.__delete__(self)
    else:
       del self.__dict__[name]

您可以通过查看以下代码来了解

__delete__
何时被调用:

class desc:
    def __delete__(descriptor, instance_of_Klaus):
        print("attribute was deleted")

class Klaus:
    d = desc()
    def __init__(self):
        pass

my_instance = Klaus()
del my_instance.d

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

del my_instance.d
delattr(my_instance, "d")
Klaus.d.__delete__(my_instance)
© www.soinside.com 2019 - 2024. All rights reserved.