理解python的類實例化
class type(name, bases, dict)
官方定義
object.__new__(cls[, ...])
官方定義
Customizing class creation 定制類創建 官方文檔
Built-in Types 內建類型 官方文檔
準備知識
- 當一個類定義被執行,發生了這些事:
- 一個合適的元類被確定
- 類命名空間被準備好
- 類主體被執行
- 類對象被創建
- 類中定義的
__new__(cls[, ...])
方法用來創建類cls的一個新實例,它是特殊的不用聲明的靜態方法。 - 類中對
__call__
方法的定義意味著對該類的實例的括號運算符的重載。 -
type(x)
返回x
的類型。類是元類的實例(Python中一切皆對象,類也是對象,對象是類的實例,只不過類的類是特殊的元類),所以int
的類是type
(元類)。表示構造關系。整型1由int類構造,int類由元類構造。(類名+括號運算符調用類的構造函數,類定義的過程即是元類實例化的過程,元類中實現了構造類的規則)。
a = 1
type(a)
# int
type(int)
# type
-
x.__mro__
返回類x
的所有超類(父類)(包括x
自身)(MRO-方法解析順序),表示類之間的繼承關系,int
繼承object
。繼承關系和構造關系是兩回事。
int.__mro__
# (int, object)
實驗
理解
MyType
繼承type
并重載type
中的方法,是我們自定義的元類。指定類MyTypeInstance
的元類為MyType
意味著用MyType
來構建類MyTypeInstance
。MyType
中重載的__new__
和__init__
方法影響類MyTypeInstance
的定義過程。__new__
可以控制類名與類屬性的審查,__init__
可以增加或修改類的屬性。而MyType
的__call__
方法則控制類MyTypeInstance
的實例化過程。MyType
的元類默認是type
(與繼承type
無關),即MyType
是type
的實例,亦即MyType = type(name, bases, dict)
,MyType
的定義過程(即type
類的實例化過程)調用的是type
的__call__
方法。
__new__
是靜態方法,__call__
和__init__
是實例方法。實際上isinstance(type, type)
得到True
,即type
是type
的實例,type
調用__call__
方法也就說得通了,也就是type
實例+()
運算符 等于type
實例調用了它的類type
中定義的__call__
實例方法。在__call__
方法中先調用__new__
靜態方法來產生一個python對象,然后調用type
實例的__init__
方法修改新對象的屬性。