問題來源:為什麼定義元類和自定義元類時,在呼叫父類的__new__方法時都是需要顯式傳遞cls的,而__init__在呼叫父類__init__方法時就是隱式的。
# 自定義元類
class MyMeta(type):
def __new__(cls, name, bases, dct):
print(f"Creating class {name} using MyMeta")
return super().__new__(cls, name, bases, dct)
def __init__(cls, name, bases, dct):
print(f"Initializing class {name} using MyMeta")
super().__init__(name, bases, dct)
# 使用自定義元類建立類
class MyClass(metaclass=MyMeta):
def __new__(cls, *args, **kwargs):
print(f"Creating an instance of {cls.__name__}")
instance = super().__new__(cls,*args, **kwargs) # 呼叫父類的 __new__ 方法
return instance
def __init__(self, name):
print(f"Initializing an instance of {self.__class__.__name__}")
self.name = name
def __call__(self):
print(f"Instance of {self.__class__.__name__} is being called!")
# 例項化 MyClass
print("\n-- Step 1: Create an instance --")
obj = MyClass("Alice")
# 呼叫例項
print("\n-- Step 2: Call the instance --")
obj()
原因:這是因為__new__是靜態方法,不依賴於例項呼叫,而依賴於類本身。 因此,Python 要顯式地將 cls 傳遞給__new__方法。
那麼為什麼 cls 需要顯式傳遞?
在元類中,cls 是動態決定的
在元類的 __new__ 方法中,cls 代表將要建立的類。
• 呼叫 super().__new__(cls, name, bases, dct) 時:
• super() 呼叫的是父類(通常是 type)的 __new__ 方法。
• cls 需要明確告訴 type.__new__ 它要建立哪個類。
• type.__new__ 會根據 cls 建立一個類。
具體呼叫流程:
• Python 呼叫元類的 __new__ 時,會顯式傳遞 cls。
• 元類的 __new__ 需要將 cls 傳遞給 type.__new__,否則父類不知道該建立哪個類。