[英]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__
)。
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
语句:“删除名称会从本地或全局命名空间中删除该名称的绑定……属性引用、订阅和切片的删除将传递给所涉及的主要对象……”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__
__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)
__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_var
或getattr(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.