類的創建過程
以下說的類指的類本身,例如以下代碼:
class Foo:
def __init__(self):
pass
則指的 Foo
的創建過程,而不是 Foo
的實例。
1. 解析 MRO
記錄(Resolving MRO entries)
根據 MRO
規則解析繼承關係
2. 確定元類(Determining the appropriate metaclass)
查找元類的過程遵循以下規則:
-
如果沒有基類且沒有指定
metaclass
,則使用type()
- 如果指定了
metaclass
且它不是type()
的實例,則直接使用metaclass
- 如果指定了
type()
實例的metaclass
或者有基類,(the most derived metaclass is used. ??)
3. 準備命名空間(Preparing the class namespace)
當元類確定後,類的命名空間也可以確定了。 如果元類有 __prepare__
屬性,則 namespace = metaclass.__prepare__(name, bases, **kwargs)
,否則命名空間會初始化爲有序的空map(empty ordered mapping.)
4. 執行 Class
內語句(Executing the class body)
類內的語句通過 exec(body, globals(), namespace)
來執行。與正常的 exec()
不同的是當類定義在一個函數內部時其可以訪問當前和外層的作用域。
即使在函數內定義的類,其內部的方法也無法訪問類的作用域。類內的定義的變量通過類實例或類對象來訪問,或者通過 __class__
。
5. 創建類對象(Creating the class object)
經過以上步驟後,通過 metaclass(name, bases, namespace, **kwargs)
來創建類。
關於 __init__
以上步驟是創建類自身。例如開頭的例子,以上步驟只是創建了 Foo
,__init__
是類實例化後才執行的,f = Foo()
這時候纔會執行 __init__