您好,我最近正在尋找metaclassPython 中的內容。
我了解到我們可以通過這種方式將元類附加到一個類:
class Metaclass(type):
...
class MyClass(metaclass=Metaclass):
...
- 第一個問題
metaclass=...我想知道上面例子中關鍵字引數()的原理是什么。檔案中似乎沒有描述
我知道函式有關鍵字引數,但我從未見過在類繼承中出現這種形式。
- 第二個問題
我們知道我們可以通過type()這種方式使用函式創建一個類
cls = type(class_name, (base_class,), {func_name: func_ref})
考慮到表單,在使用而不是關鍵字metaclass=...創建類時如何傳遞元類?type()class
謝謝stackoverflowers!
uj5u.com熱心網友回復:
通常,與class陳述句一起使用的關鍵字引數被傳遞給__init_subclass__, 以便在該函式認為合適的情況下使用。metaclass但是,代碼生成器本身使用它來確定呼叫什么來定義類。
元類不是要傳遞給呼叫的引數type;它是被呼叫的可呼叫物件,而不是. type非常粗略地說,
class MyClass(metaclass=Metaclass):
...
變成了
MyClass = Metaclass('MyClass', (), ...)
type只是默認的元類。
(如何class執行陳述句的詳細資訊可以在語言檔案的第 3.3.3 節中找到。)
請注意,元類不必是type. 你可以用元類做一些真正可怕的事情,比如
>>> class A(metaclass=lambda x, y, z: 3): pass
...
>>> type(A)
<class 'int'>
>>> A
3
元類回傳什么并不重要,只要它接受 3 個引數即可。
但是,請不要撰寫這樣的實際代碼。class陳述句應該產生至少類似于型別的東西。
從某種意義上說,class陳述不如其他陳述那么神奇。def例如,不能自定義陳述句以生成除 的實體之外的其他內容,并且通過顯式呼叫function來創建物件要困難得多。functiontypes.FunctionType
uj5u.com熱心網友回復:
是的,我看過這個,但它沒有提供有關類繼承中關鍵字引數原則的資訊,我仍然感到困惑
metaclass=...不是關于繼承。
Python 中的一切都是物件。因此,當您定義一個類時MyClass,不僅是MyClass()一個物件,而且類MyClass本身也是一個物件。
MyClass()是 的一個實體MyClass,很簡單。
但是如果MyClass也是一個物件,它是什么類的實體呢?
如果你什么都不做,物件 (!)MyClass就是類的一個實體type。
如果你這樣做,class MyClass(metaclass=Metaclass)那么MyClass是Metaclass.
考慮
class Metaclass(type):
pass
class MyClass1:
pass
class MyClass2(metaclass=Metaclass):
pass
兩者都MyClass1繼承MyClass2自object且僅object。
>>> MyClass1.__mro__
(<class '__main__.MyClass1'>, <class 'object'>)
>>> MyClass2.__mro__
(<class '__main__.MyClass2'>, <class 'object'>)
但它們的型別不同:
>>> type(MyClass1)
<class 'type'>
>>> type(MyClass2)
<class '__main__.Metaclass'>
你什么時候需要這個?通常,你不會。當你這樣做的時候,你就在做那種你已經知道為什么和如何做的元編程。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/428625.html
