简体   繁体   English

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

[英]What is the difference between `__del__` and `__delete__`?

Suppose someone didn't know what the difference was between __del__ and __delete__ ?假如有人不知道有什么不同之间__del____delete__ Write an explanation.写一个解释。

object.__del__(self) : object.__del__(self)

Called when the instance is about to be destroyed.在实例即将被销毁时调用。 This is also called a finalizer or (improperly) a destructor.这也称为终结器或(不正确地)析构函数。 If a base class has a __del__() method, the derived class's __del__() method, if any, must explicitly call it to ensure proper deletion of the base class part of the instance.如果基类具有__del__()方法,则派生类的__del__()方法(如果有)必须显式调用它以确保正确删除实例的基类部分。

I think this means that my_object.__del__ will get called by CPython's garbage collector after the reference count for my_object drops to zero.我认为这意味着my_object.__del__将在my_object的引用计数降至零后被 CPython 的垃圾收集器调用。

object.__delete__(self, instance) : object.__delete__(self, instance)

Called to delete the attribute on an instance instance of the owner class.调用以删除所有者类的实例instance上的属性。

The __delete__ dunder method is related to python's notion of descriptors ; __delete__ dunder 方法与 python 的描述符概念有关; a descriptor is "any object which defines the methods __get__() , __set__() , or __delete__() ."描述符是“定义__get__()__set__()__delete__()方法的任何对象。” Descriptors can be used to implement custom behavior for attribute lookup/assignment/deletion (via __get__ / __set__ / __delete__ , respectively).描述符可用于实现属性查找/分配/删除的自定义行为(分别通过__get__ / __set__ / __delete__ )。

See also:也可以看看:

  • The del statement : "Deletion of a name removes the binding of that name from the local or global namespace... Deletion of attribute references, subscriptions and slicings is passed to the primary object involved..." del语句:“删除名称会从本地或全局命名空间中删除该名称的绑定……属性引用、订阅和切片的删除将传递给所涉及的主要对象……”
  • The delattr built-in function. delattr内置函数。 From the docs, "The function deletes the named attribute, provided the object allows it. For example, delattr(x, 'foobar') is equivalent to del x.foobar ."从文档中,“该函数删除命名属性,前提是对象允许它。例如, delattr(x, 'foobar')等效于del x.foobar 。”
  • object.__delattr__(self, name) is called when attribute deletion is attempted. object.__delattr__(self, name)在尝试删除属性时被调用。 According to the docs, "This should only be implemented if del obj.name is meaningful for the object."根据文档,“只有当del obj.name对对象有意义时,才应该实现这一点。” Thus, defining a user class with the method MyClass.__delattr__ enables custom behavior when eg the statement del my_object.an_attr is invoked, or (equivalently) when delattr(my_object, 'an_attr') is called.因此,使用MyClass.__delattr__方法定义用户类可以在调用语句del my_object.an_attr或(等效地)调用delattr(my_object, 'an_attr')时启用自定义行为。
  • object.__delitem__(self, key) is "Called to implement deletion of self[key] ." object.__delitem__(self, key)是“调用以实现self[key]删除。” Thus, defining a user class with the method MyClass.__delitem__ enables custom behavior when eg the statement del my_object[a_key] is invoked.因此,使用MyClass.__delitem__方法定义用户类可启用自定义行为,例如调用语句del my_object[a_key]

__del__ is called when you delete an object and __delete__ is sometimes called when you delete an attribute of an object. __del__ ,当你删除一个对象被调用, __delete__当你删除一个对象的属性有时也被称为。

del x.my_num    # __delete__
del x           # __del__            

ABOUT __del__:关于__del__:

The following code shows when __del__ gets called:以下代码显示__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

If my_instance is the last label pointing to the data, then del my_instance calls MyClass.__del__(my_instance)如果my_instance是指向数据的最后一个标签,则del my_instance调用MyClass.__del__(my_instance)

Technically, del my_instance only deletes the label my_instance .从技术上讲, del my_instance只会删除标签my_instance Imagine people at a party all wearing names tags.想象一下参加聚会的人都戴着名牌。 Sometimes a person has 6 or 7 names tags on simultaneously, and other times, they only have one.有时一个人同时有 6 或 7 个姓名标签,而其他时候,他们只有一个。 Python will kick anyone out of the party who is not wearing at least one name tag. Python 会将任何没有佩戴至少一个名牌的人踢出派对。 MyClass.__del__(my_instance) gets called when the last name-tag/label is removed from a piece of data. MyClass.__del__(my_instance)在从一段数据中删除姓氏标签/标签时被调用。

The code above shows an example of when we make sure to close an open file.上面的代码显示了我们何时确保关闭打开的文件的示例。 Another example might be to count of the number active instances of a given class:另一个例子可能是计算给定类的活动实例数:

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)

ABOUT __delete__关于__delete__

Unlike __del__ , __delete__ has to do with descriptors.不像__del____delete__与描述的事情。 The code below describes the behavior of obj.my_var or getattr(obj, “my_var”)下面的代码描述了obj.my_vargetattr(obj, “my_var”)

class Klaus: def getattribute (self, attrname): try: attribute = attrname from instance Klaus except AttributeError: attribute = attrname from class Klaus class Klaus: def getattribute (self, attrname): try: attribute = attrname from instance Klaus 除了 AttributeError: attribute = attrname from class Klaus

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

    return attribute

If my_var is a descriptor, then following two lines of code equivalent:如果my_var是一个描述符,那么下面两行代码等效:

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

Just as __getattribute__ checks whether the attribute has a __get__ method or not, __delattr__ will check whether the attribute has a __delete__ method or not.就像__getattribute__检查属性是否有__get__方法一样, __delattr__将检查属性是否有__delete__方法。

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

You can see when __delete__ gets called by viewing the following code:通过查看以下代码,您可以看到__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

When dealing with descriptors, the following lines of code are all equivalent:在处理描述符时,以下几行代码都是等价的:

del my_instance.d
delattr(my_instance, "d")
Klaus.d.__delete__(my_instance)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM