Python 物件系統建立在兩大核心關係之上:類型關係(由誰建立)與繼承關係(誰繼承誰)。本文從 type 元類、__class__、__bases__、__metaclass__ 等底層機制出發,系統闡述新式類與經典類的差異,幫助開發者建立正確的物件模型心智圖。
>> type(int)
>>> type(type)
# type 自己是自己的實例(元類的遞歸定義)
>>> class A(object): pass
>>> A.__class__
>>> type(A)
object)的類型都是 type。type 本身也是類別,其類型同為 type(類似根目錄的父目錄是自己)。
type (根)
├── 內建型別: int, str, list, dict, ...
├── 使用者定義類別 (class A)
│ └── 實例
└── 元類 (class MyMeta(type))
└── 使用者定義類別 (class B, __metaclass__=MyMeta)
└── 實例
每個物件的 __class__ 指向其類別;每個類別的 __class__ 指向 type(或其子類)。
>> class A(object): pass
>>> class B(A): pass
>>> B.__bases__
(,)
>>> issubclass(B, A)
True
>>> isinstance(B(), A)
True
object 為根。type 繼承自 object(type.__bases__ == (object,))。object 的類型是 type(object.__class__ is type)。# 等價於 class A(object): def f(self): print(1)
def f(self): print(1)
A = type('A', (object,), {'f': f})
del f
class 關鍵字本質是語法糖,編譯後呼叫 type.__new__。class MyMeta(type):
def __new__(mcs, name, bases, attrs):
print(f"Creating class {name}")
return super(MyMeta, mcs).__new__(mcs, name, bases, attrs)
class MyClass(object):
__metaclass__ = MyMeta # Python 2 語法
# Python 3: class MyClass(metaclass=MyMeta):
元類允許攔截類別建立過程,實現屬性驗證、自動註冊、AOP 等進階模式。
| 特性 | 經典類 | 新式類 |
|---|---|---|
| 定義 | class A: | class A(object): |
| 類型 | types.ClassType | type |
__class__ | 無 | 有 |
| MRO | 深度優先 | C3 線性化 |
super() | 不支援 | 支援 |
| 描述器/屬性 | 不支援 | 完整支援 |