Python 元類機制的工作流程及引數呼叫的不同

EricS9999發表於2024-12-01
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。

相關文章