12.01 Python中


Python中 __call__() 與__del__() 方法詳解


__call__() 方法

如果類中定義了__call__() 方法,那麼該類的實例可以作為函數調用,也就是說,假如在Person類中實現如下方法:"def __call__(self, *args)" 。 若將Person 類的一個實例化對象賦值於person_info 變量。那麼調用 "person_info.__call__(1,2)" 等同於調用 "person_info(1,2)" 。同時,使用 "person_info(1,2)" 這種調用方式不影響實例本身的生命週期(__call__()不影響一個實例的構造和析構)。

__call__()方法可以用來改變實例的內部成員的值,對於一些類的實例中需要頻繁改變狀態的場景,使用這種方式是一種比較優雅的做法。

Python中 __call__() 與__del__() 方法詳解

執行上述代碼,輸出結果為:

Python中 __call__() 與__del__() 方法詳解



__del__() 方法

Python 引用計數機制是實現垃圾回收的主要機制之一,當有一個變量引用該 Python 對象時,該對象引用計數為 1,當有兩個變量引用該 Python 對象時,該對象引用計數為 2,依此類推,如果一個對象的引用計數變成了 0,則說明程序中不再有變量引用該對象,即不再需要該對象,因此 Python 就會回收該對象。

與__init__() 方法對應的是__del__() 方法,實例化對象時,Python解釋器默認調用__init__() 方法對類實例對象進行初始化。當刪除一個對象時,Python解釋器也會默認調用一個方法,這個方法為__del__() 方法銷燬類實例化對象,即在任何 Python 對象將要被系統回收之時,系統都會自動調用該對象的__del__() 方法。

Python中 __call__() 與__del__() 方法詳解

上述代碼,運行

"person_info = Person('Tom', 18)" 在內存中創建了一個 Person 類的實例化對象,並且讓變量 person_info 引用該 Person類的實例化對象。"del person_info" 刪除變量 person_info(刪除 Person類的實例化對象的引用) , 此時內存中的 Person類的實例化對象沒有任何變量對其引用,Python解析器就會回調 __del__() 方法,回收內存。執行上述代碼,輸出結果為:

Python中 __call__() 與__del__() 方法詳解


當一個對象被垃圾回收時,Python 就會自動調用該對象的__del__()方法。需要注意的是,

不要認為對一個變量執行__del__() 操作,該變量所引用的對象就會被回收,只有當對象的引用計數變成 0 時,該對象才會被回收。因此,如果一個對象有多個變量引用它,那麼 del 其中一個變量是不會回收該對象的。代碼示例如下:

Python中 __call__() 與__del__() 方法詳解

上述代碼中,person_info 和 person_info1 同時引用同一個Person類的實例化對象(同一個內存地址),執行 "del person_info" 刪除 person_info 變量時,刪除的是該變量對應的引用,此時由於內存中的 Person類的實例對象還在被 person_info1 變量引用,引用計數不為0,所以不會回收該內存(不會回調__del__()方法)。當再執行

"del person_info1" 刪除 person_info1變量後,內存中的Person類的實例對象已經沒有引用的變量,此時引用計數為0,解釋器會對內存進行回收,回調__del__()方法,執行上述代碼,輸出結果為:

Python中 __call__() 與__del__() 方法詳解


分享到:


相關文章: