1. 程式人生 > >元類相關(type & metaclass)

元類相關(type & metaclass)

type 不同 ans -s family 1.2 的人 elf 創建

"""
metaclass作用:

1) 攔截類的創建

2) 修改類

3) 返回修改之後的類

"""


"""
為什麽要用metaclass類而不是函數?

由於__metaclass__可以接受任何可調用的對象,那為何還要使用類呢,因為很顯然使用類會更加復雜啊?這裏有好幾個原因:

1) 意圖會更加清晰。當你讀到UpperAttrMetaclass(type)時,你知道接下來要發生什麽。

2) 你可以使用OOP編程。元類可以從元類中繼承而來,改寫父類的方法。元類甚至還可以使用元類。

3) 你可以把代碼組織的更好。當你使用元類的時候肯定不會是像我上面舉的這種簡單場景,通常都是針對比較復雜的問題。將多個方法歸總到一個類中會很有幫助,也會使得代碼更容易閱讀。

4) 你可以使用__new__, __init__以及__call__這樣的特殊方法。它們能幫你處理不同的任務。就算通常你可以把所有的東西都在__new__裏處理掉,有些人還是覺得用__init__更舒服些。

5) 哇哦,這東西的名字是metaclass,肯定非善類,我要小心!

究竟為什麽要使用元類?

現在回到我們的大主題上來,究竟是為什麽你會去使用這樣一種容易出錯且晦澀的特性?好吧,一般來說,你根本就用不上它:

“元類就是深度的魔法,99%的用戶應該根本不必為此操心。如果你想搞清楚究竟是否需要用到元類,那麽你就不需要它。那些實際用到元類的人都非常清楚地知道他們需要做什麽,而且根本不需要解釋為什麽要用元類。” —— Python界的領袖 Tim Peters
"""

"""
知識點:
對象是類創建。創建對象時,類裏面的__init__方法會自動執行。 對象()會執行類的__call__方法。
類是type創建。創建類時,type的__init__方法會自動執行。 類()會執行執行type的__call__方法。執行完__call__方法後,call方法不僅會調用類的__new__方法,還會調用類的__init__方法。

# 第0步: 執行type的 __init__ 方法【類是type的對象】
class Foo:
def __init__(self):
pass

def __call__(self, *args, **kwargs):
pass # 第1步: 執行type的 __call__ 方法 # 1.1 調用 Foo類(是type的對象)的 __new__方法,用於創建對象。 # 1.2 調用 Foo類(是type的對象)的 __init__方法,用於對對象初始化。 obj = Foo() # 第2步:執行Foo def __call__ 方法 obj()


"""

元類相關(type & metaclass)