class Mymeta(type):
def __new__(cls, name, bases, dct):
print(f'Mymeta.__new__: cls={cls}, id(cls)={id(cls)}')
return super().__new__(cls, name, bases, dct)
def __init__(cls, name, bases, dct):
print(f'Mymeta.__init__: cls={cls}, id(cls)={id(cls)}')
super().__init__(name, bases, dct)
type元類機制會呼叫__call__方法,執行__new__,再執行__init__
1. Python 元類機制的工作流程
在元類的上下文中,__new__ 和 __init__ 的呼叫順序和邏輯如下:
1. 呼叫 __new__:
• __new__ 的任務是 建立類物件。
• 此時,name、bases 和 dct 描述的是類的定義資訊。
• 返回值是類物件(如 MyClass)。
2. 呼叫 __init__:
• __init__ 的任務是對 __new__ 建立的類物件進行 初始化。
• 此時,name、bases 和 dct 仍然是類的定義資訊。
雖然 __new__ 和 __init__ 的引數(name, bases, dct)看起來是相同的,但它們在呼叫時所操作的 cls 物件不同:
• 在 __new__ 中,cls 是元類本身(如 Mymeta),因為 __new__ 是由元類呼叫,用於建立類物件。
• 在 __init__ 中,cls 是剛剛透過 __new__ 建立的類物件(如 MyClass),因為 __init__ 的任務是初始化這個類物件。
cls 的值不同是關鍵
• 在 __new__ 中:
• cls 是元類 Mymeta,因為它負責 建立類物件。
• 在 __init__ 中:
• cls 是透過 Mymeta.__new__ 建立出來的類物件(如 MyClass)。
• __init__ 的任務是初始化 MyClass。