簡體   English   中英

`__del__` 和 `__delete__` 有什么區別?

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

假如有人不知道有什么不同之間__del____delete__ 寫一個解釋。

object.__del__(self)

在實例即將被銷毀時調用。 這也稱為終結器或(不正確地)析構函數。 如果基類具有__del__()方法,則派生類的__del__()方法(如果有)必須顯式調用它以確保正確刪除實例的基類部分。

我認為這意味着my_object.__del__將在my_object的引用計數降至零后被 CPython 的垃圾收集器調用。

object.__delete__(self, instance)

調用以刪除所有者類的實例instance上的屬性。

__delete__ dunder 方法與 python 的描述符概念有關; 描述符是“定義__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]

__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_vargetattr(obj, “my_var”)

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

如果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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM