在一個名爲exp.py(下面)的文件中,我試圖理解Python中的元類。Python元類行爲(不調用__new__),是否有解釋?
class A(type):
def __new__(cls, name, bases, dct):
print "cls is: ", cls
print "name is: ", name
print "bases is: ", bases
print "dct is: ", dct
print
return super(A, cls).__new__(cls, name, bases, dct)
class B(object):
__metaclass__ = A
class C(B): pass
class D(type):
def __new__(cls, name, bases, dct):
print "cls is: ", cls
print "name is: ", name
print "bases is: ", bases
print "dct is: ", dct
return type(name, bases, dct)
class E(object):
__metaclass__ = D
class F(E): pass
在終端:看來當元類的__new__
方法使用的「類型」的構造函數構造一類像,其__new__
方法沒有得到一個類的子類使用它作爲元類稱爲
>>> from exp import *
cls is: <class 'exp.A'>
name is: B
bases is: (<type 'object'>,)
dct is: {'count': 0, '__module__': 'exp', '__metaclass__': <class 'exp.A'>, '__init__': <function __init__ at 0x107eb9578>}
cls is: <class 'exp.A'>
name is: C
bases is: (<class 'exp.B'>,)
dct is: {'__module__': 'exp'}
cls is: <class 'exp.D'>
name is: E
bases is: (<type 'object'>,)
dct is: {'count': 0, '__module__': 'exp', '__metaclass__': <class 'exp.D'>, '__init__': <function __init__ at 0x107ebdb18>}
>>>
正如你所看到的,當類F的定義被加載時,元類D的__new__
方法不會被調用。 (如果它已被調用,那麼關於F級的信息也將被打印。)
有人可以幫我解釋一下嗎?
相關崗位:我讀What is a metaclass in Python?,而且似乎遇到了一句類似的話,「這裏需要的__metaclass__
屬性不會被繼承小心,父(Bar.__class__
)的元類將是如果。 Bar使用了__metaclass__
屬性,該屬性創建了帶有type()
的Bar(而不是type.__new__()
),該子類不會繼承該行爲。「但我並沒有完全理解這一點。
大回答謝謝!順便說一下,我對這句話有一些疑問,「(這首先查找'__class__'屬性,如果找不到,則使用它的類型)」。 1.在什麼情況下會找不到'__class__'屬性? 2.在什麼類型的情況下,類的'__class__'屬性與它的類型不同(用'type()'確定)?謝謝 – platypus 2015-02-11 23:26:12
@platypus舊式類沒有這個屬性,甚至'type()'的輸出也不一樣。對於新式類,默認類型是'type',對於舊式類,它是'classobj'。 [新風格和經典類](https://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes) – 2015-02-11 23:55:31