標籤:

也說Python元類

要搞懂元類,咱們還是得先從對象說起

對象(Object)

Python 一切皆對象,這句話你一定有聽說過(現在你就聽說了),一個數字是對象,一個字元串是對象,一個列表是對象,一個字典是對象,例如:

>>> i = 10n>>> s = "abc"n>>> nums = [1,2,3]n>>> dicts = {"name":"zhang"}n

等號右邊是對象,左邊是給這些對象取的名字,任何對象都有3個關鍵屬性:標識、值、類型。

標識

標識就和人的身份證ID一樣,每個對象有唯一ID標識,在整個生命周期中都不會變,你可以認為標識是這個對象在計算機內存中的地址。通過函數 id() 可以查看對象的ID標識。

>>> id(i)n40592592n>>> id(s)n44980584n

對象值

對象的第二個屬性是值,值很好理解,比如 i 的值是 10,s 的值是 abc,nums 的值就是 1,2,3。

類型

對象還有一個很重要的屬性就是類型,任何對象都有屬於自己的類型,對象就是通過它所屬的類型構造出來的,比如上面的 i 的類型是 int 類型,這個對象就是由 int 構造出來的。s 類型是字元串類型,nums 的類型是列表類型,dicts 的類型是字典類型,它們都是由對應的類型構建出來的。

通過 type() 可以查看對象的類型。

>>> type(i)n<class int>n>>> type(s)n<class str>n>>> type(nums)n<class list>n>>> type(dicts)n<class dict>n

對象的類型也和ID標識一樣,確定好之後就不會再變化了。

類與(實例)對象

除了系統已經定義好了的整數類型,字元串類型,列表等類型之外,我們還可以創建自己的類型,用關鍵字 class 來定義。例如:

>>> class Person:n # 這裡的 self 指某個實例對象自己n... def __init__(self, name):n # name 是實例的屬性n... self.name = namen # live 是類的屬性n live = Truen

這裡的 Person 就是自定義類,類是一個抽象的模版,既不指張三也不是李四,現在我們可以通過調用這個類來構造(實例化)出一個具體的,實在的,有名字的對象出來,這個對象稱之為實例對象。

>>> p1 = Person("zhangsan")n>>> p1.namenzhangsann>>>n>>> p2 = Person("lisi")n>>> p2.namenlisin

這裡的 p1、p2 就是實例化之後的(實例)對象,這兩個對象的類型都是 Person 類,類與(實例)對象的關係就像一個車輛模具與一輛被造出來的真實車的關係一樣。

>>> p1n<__main__.Person object at 0x0195AA30>n>>> type(p1)n<class __main__.Person> # 這裡的__main__是模塊名稱n

類也是對象(又叫類對象)

剛剛我們說了一切都是對象,實例(真實車)是對象,類(模具)當然也是對象,因為它也是個實實在在存在的東西,

當 Python 解釋器執行到關鍵字 class 這個指令的時候,在內部就會創建一個名為 "Person" 的類,這個類也是個對象,我們稱之為類對象(注意區別實例對象),它一樣有ID標識、有類型、有值。例如:

>>> id(Person)n26564024n>>> type(Person)n<class type>n>>> Personn<class __main__.Person>n

我們注意到這個 Person 這個類對象的類型叫 「type」,也就是說 Person 類是由 type 創建出來的,現在你要記住,p1,p2 是實例對象,而 Person 是類對象。另外,這個 type 是什麼鬼?

我們來回顧一下,實例對象 p1 的類型是類對象 Person,Person 的類型 type

>>> nums = [1,2,3]n>>> type(nums)n<class list>n>>> type(list)n<class type>n

nums 的類型是 list,list 的類型也是 type,字典類(dict)的類型也是 type,所有類的類型都是 type,也就是說所有的類都是由type 創建的。這個 type 就是元類,道生一,一生二,三生萬物,元類就是 Python 中的造物主。(元類自己也是對象)

現在我們都知道類(對象)可以使用 class 關鍵字創建,我們還知道類(對象)的類型是 type,既然知道了它的類型是 type,那麼肯定可以通過 type(元類)來創建。

用元類創建類

前面講到過,type 有一個作用是用於檢查對象的類型,其實它還有另外一個作用就是作為元類動態地創建類(對象)。

>>> Person = type("Person", (), {"live":True})n>>> Personn<class __main__.Person>n

Person 就是一個類,它等價於:

>>> class Person:n... live = Truen...n>>> Personn<class __main__.Person>n

用元類 type 創建類的語法是:

type(類名,基類元組(可以為空), 屬性字典)n

那麼元類到底有什麼用處呢?我們真的需要元類嗎?

歡迎關注公眾號:Python之禪(id:vttalk)


推薦閱讀:

Python 關於讀寫txt的問題?
爬蟲入門系列(一):快速理解 HTTP 協議
我用Hexo寫博客
C/C++ 這類更底層的語言,如果把平時常用的高級函數和功能都實現,能否達到 Python 的開發效率?

TAG:Python |