中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中的魔術方法是什么

發布時間:2020-09-24 14:01:54 來源:億速云 閱讀:150 作者:Leah 欄目:編程語言

今天就跟大家聊聊有關Python中的魔術方法是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

介紹

在Python中,所有以“__”雙下劃線包起來的方法,都統稱為“Magic Method”,中文稱『魔術方法』,例如類的初始化方法 __init__ ,Python中所有的魔術方法均在官方文檔中有相應描述,但是對于官方的描述比較混亂而且組織比較松散。很難找到有一個例子。

構造和初始化

每個Pythoner都知道一個最基本的魔術方法, __init__ 。通過此方法我們可以定義一個對象的初始操作。然而,當調用 x = SomeClass() 的時候, __init__ 并不是第一個被調用的方法。實際上,還有一個叫做__new__ 的方法,兩個共同構成了“構造函數”。

__new__是用來創建類并返回這個類的實例, 而__init__只是將傳入的參數來初始化該實例。

在對象生命周期調用結束時,__del__ 方法會被調用,可以將__del__理解為“構析函數”。下面通過代碼的看一看這三個方法:

from os.path import join
class FileObject:
    '''給文件對象進行包裝從而確認在刪除時文件流關閉'''
    def __init__(self, filepath='~', filename='sample.txt'):
        #讀寫模式打開一個文件
        self.file = open(join(filepath, filename), 'r+')
    def __del__(self):
        self.file.close()
        del self.file

控制屬性訪問

許多從其他語言轉到Python的人會抱怨它缺乏類的真正封裝。(沒有辦法定義私有變量,然后定義公共的getter和setter)。Python其實可以通過魔術方法來完成封裝。我們來看一下:

__getattr__(self, name):

定義當用戶試圖獲取一個不存在的屬性時的行為。這適用于對普通拼寫錯誤的獲取和重定向,對獲取一些不建議的屬性時候給出警告(如果你愿意你也可以計算并且給出一個值)或者處理一個 AttributeError 。只有當調用不存在的屬性的時候會被返回。

__setattr__(self, name, value):

與__getattr__(self, name)不同,__setattr__ 是一個封裝的解決方案。無論屬性是否存在,它都允許你定義對對屬性的賦值行為,以為這你可以對屬性的值進行個性定制。實現__setattr__時要避免"無限遞歸"的錯誤。

__delattr__:

與 __setattr__ 相同,但是功能是刪除一個屬性而不是設置他們。實現時也要防止無限遞歸現象發生。

__getattribute__(self, name):

__getattribute__定義了你的屬性被訪問時的行為,相比較,__getattr__只有該屬性不存在時才會起作用。因此,在支持__getattribute__的Python版本,調用__getattr__前必定會調用 __getattribute__。__getattribute__同樣要避免"無限遞歸"的錯誤。需要提醒的是,最好不要嘗試去實現__getattribute__,因為很少見到這種做法,而且很容易出bug。

在進行屬性訪問控制定義的時候很可能會很容易引起“無限遞歸”。如下面代碼:

#  錯誤用法
def __setattr__(self, name, value):
    self.name = value
    # 每當屬性被賦值的時候(如self.name = value), ``__setattr__()`` 會被調用,這樣就造成了遞歸調用。
    # 這意味這會調用 ``self.__setattr__('name', value)`` ,每次方法會調用自己。這樣會造成程序崩潰。
#  正確用法
def __setattr__(self, name, value):
    self.__dict__[name] = value  # 給類中的屬性名分配值
    # 定制特有屬性

創建自定義容器

有很多方法可以讓你的Python類行為向內置容器類型一樣,比如我們常用的list、dict、tuple、string等等。Python的容器類型分為可變類型(如list、dict)和不可變類型(如string、tuple),可變容器和不可變容器的區別在于,不可變容器一旦賦值后,不可對其中的某個元素進行修改。

在講創建自定義容器之前,應該先了解下協議。這里的協議跟其他語言中所謂的"接口"概念很像,它給你很多你必須定義的方法。然而在Python中的協議是很不正式的,不需要明確聲明實現。事實上,他們更像一種指南。

自定義容器的magic method

下面細致了解下定義容器可能用到的魔術方法。首先,實現不可變容器的話,你只能定義 __len__ 和 __getitem__ (下面會講更多)。可變容器協議則需要所有不可變容器的所有,另外還需要 __setitem__ 和 __delitem__ 。如果你希望你的對象是可迭代的話,你需要定義 __iter__ 會返回一個迭代器。迭代器必須遵循迭代器協議,需要有 __iter__(返回它本身) 和 next。

__len__(self):

返回容器的長度。對于可變和不可變容器的協議,這都是其中的一部分。

__getitem__(self, key):

定義當某一項被訪問時,使用self[key]所產生的行為。這也是不可變容器和可變容器協議的一部分。如果鍵的類型錯誤將產生TypeError;如果key沒有合適的值則產生KeyError。

__setitem__(self, key, value):

當你執行self[key] = value時,調用的是該方法。

__delitem__(self, key):

定義當一個項目被刪除時的行為(比如 del self[key])。這只是可變容器協議中的一部分。當使用一個無效的鍵時應該拋出適當的異常。

__iter__(self):

返回一個容器迭代器,很多情況下會返回迭代器,尤其是當內置的iter()方法被調用的時候,以及當使用for x in container:方式循環的時候。迭代器是它們本身的對象,它們必須定義返回self的__iter__方法。

__reversed__(self):

實現當reversed()被調用時的行為。應該返回序列反轉后的版本。僅當序列可以是有序的時候實現它,例如對于列表或者元組。

__contains__(self, item):

定義了調用in和not in來測試成員是否存在的時候所產生的行為。你可能會問為什么這個不是序列協議的一部分?因為當__contains__沒有被定義的時候,如果沒有定義,那么Python會迭代容器中的元素來一個一個比較,從而決定返回True或者False。

__missing__(self, key):

dict字典類型會有該方法,它定義了key如果在容器中找不到時觸發的行為。比如d = {'a': 1}, 當你執行d[notexist]時,d.__missing__['notexist']就會被調用。

看完上述內容,你們對Python中的魔術方法是什么有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

和顺县| 齐齐哈尔市| 通榆县| 闵行区| 项城市| 宝兴县| 镇原县| 桃源县| 永嘉县| 呈贡县| 民县| 巩留县| 新田县| 和政县| 全南县| 都匀市| 饶阳县| 句容市| 龙门县| 金阳县| 松潘县| 灯塔市| 靖江市| 锡林浩特市| 隆安县| 合肥市| 扎赉特旗| 文登市| 饶平县| 绥阳县| 勐海县| 湘西| 左权县| 武威市| 淮南市| 宜兰县| 乐至县| 七台河市| 藁城市| 随州市| 温泉县|