Python魔法方法

目錄:
一、構(gòu)造和初始化
二、屬性訪問控制
三、描述符協(xié)議
四、自定義容器(Container)
五、上下文管理器
六、可調(diào)用對象(__call__方法)

Python魔法方法(魔術(shù)方法)

在Python中,所有以雙下劃線包起來的方法,都統(tǒng)稱為"魔法方法"。

一、構(gòu)造和初始化

  • __new__是在實例創(chuàng)建之前被調(diào)用的。因為它的任務就是創(chuàng)建實例然后返回該實例,是個靜態(tài)方法。
  • __init__是在實例對象創(chuàng)建完成后被調(diào)用的。然后設(shè)置對象屬性的一些初始值。

二、屬性訪問控制

  • __getattr__(self, name): 訪問不存在的屬性時調(diào)用。
  • __getattribute__(self, name):訪問存在的屬性時調(diào)用(先調(diào)用該方法,查看是否存在該屬性,若不存在,接著去調(diào)用__getattr__)。
  • __setattr__(self, name, value):設(shè)置實例對象的一個新的屬性時調(diào)用。
  • __delattr__(self, name):刪除一個實例對象的屬性時調(diào)用 。

三、描述符協(xié)議

描述符是一個類,定義了訪問另一個類屬性的方式。提高屬性訪問控制代碼可復用性。

實現(xiàn)了__get__()、__set__()、__delete__() 其中至少一個方法的類,就是一個描述符:

  • 實現(xiàn)了__get__()和__set__()的描述符稱為數(shù)據(jù)描述符。
  • 只實現(xiàn)了__get__()的描述符稱為非數(shù)據(jù)描述符。
  • __get__: 用于訪問屬性。它返回屬性的值,若屬性不存在、不合法等都可以拋出對應的異常。
  • __set__:將在屬性分配操作中調(diào)用。不會返回任何內(nèi)容。
  • __delete__:控制刪除操作。不會返回內(nèi)容。

四、自定義容器(Container)

在Python中,如果我們想實現(xiàn)創(chuàng)建類似于序列和映射的類(可以迭代以及通過[下標]返回元素),可以通過重寫魔法方法__getitem__、__setitem__、__delitem__、__len__方法去模擬。

  • __getitem__(self,key):返回鍵對應的值。
  • __setitem__(self,key,value):設(shè)置給定鍵的值。
  • __delitem__(self,key):刪除給定鍵對應的元素。
  • __len__():返回元素的數(shù)量。

五、上下文管理器

1.使用類

在一個類里,如果實現(xiàn)了__enter__和__exit__方法,這個類的實例就是一個上下文管理器。
在編寫代碼時,可以將資源的連接或者獲取放在__enter__中,而將資源的關(guān)閉寫在__exit__ 中。__enter__中需要返回當前實例對象。

上下文管理器的作用:

  • 可以以一種更加優(yōu)雅的方式,操作(創(chuàng)建/獲取/釋放)資源,如文件操作、數(shù)據(jù)庫連接。
  • 可以以一種更加優(yōu)雅的方式,處理異常。(處理異常通常都是使用 try...execept... 來捕獲處理的。這樣做一個不好的地方是,在代碼的主邏輯里,會有大量的異常處理代理,這會很大的影響我們的可讀性。)
  • __enter__:進入方法。
  • __exit__:退出方法。
class ContextManager:
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        :param exc_type: 異常類型
        :param exc_val: 異常實例
        :param exc_tb: 堆棧信息(traceback對象)
        :return: 如果返回True則代表已經(jīng)正確處理異常。如果返回True以外其他值,則代表異常未處理,則將異常層層上報。
        """
        return True

示例1:

class Resource:
    def __enter__(self):
        print('===connect to resource===')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('===close resource connection===')

    def operate(self):
        print('===in operation===')


with Resource() as res:
    res.operate()
運行結(jié)果1

2.使用contextlib

以yield為分界點:

  • yield之前的代碼相當于__enter__中的代碼。
  • yield之后的值相當于__enter__的返回值。
  • yield之后的代碼相當于__exit__中的代碼。
import contextlib
@contextlib.contextmanager
def context_manager():
    # __enter__方法
    print('===connect to resource===')

    try:
        yield __enter__方法的返回值
    except Exception:
        print("拋出異常!")
        
    # __exit__方法
    print('===close resource connection===')

六、可調(diào)用對象(__call__方法)

所有的函數(shù)都是可調(diào)用對象。
一個類實例也可以變成一個可調(diào)用對象,只需要實現(xiàn)一個特殊方法__call__()。
示例:斐波那契數(shù)列

class Fib:
    def __init__(self):
        pass

    def __call__(self, num):
        a, b = 1, 1\_\_call\_\_方法
        self.list = []

        for i in range(num):
            self.list.append(a)
            a, b = b, a+b
        return self.list

    def __str__(self):
        return str(self.list)


f = Fib()
print(f(10))
運行結(jié)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 在python中,有一些內(nèi)置好的特定的方法,這些方法在進行特定的操作時會自動被調(diào)用,稱之為魔法方法,下面介紹幾種常...
    LittlePy閱讀 22,181評論 5 32
  • 1、什么叫魔法方法? 魔法方法:Python解釋器自動給出默認的,是可以給你的類增加魔力的特殊方法。如果你的對象實...
    Bling_ll閱讀 1,166評論 0 2
  • (一)魔法方法 在python中,有的名稱在前后會加上兩個下劃線,具有特殊的含義,大部分會在某些條件下自動被調(diào)用。...
    森先生_wood閱讀 1,068評論 0 4
  • linux中常用的三大文本處理器。grep, sed 和 awk 三種,可謂一個比一個高級,今天只是簡單粗略的比較...
    MrhahaKent閱讀 1,204評論 0 0
  • 假如,在古代,我想成為一名統(tǒng)帥千軍萬馬的將軍。手恃利劍,跨下烈馬,馳騁疆場。策馬奔騰,保家衛(wèi)國。 假如時空可以穿越...
    清風明月馮耀杰閱讀 243評論 0 4

友情鏈接更多精彩內(nèi)容