在名为exp.py(下面)的文件中,我试图理解Python中的元类。似乎当元类的__new__
方法使用'type'构造函数构造一个类时,它的__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
在终端:
>>> 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使用Bar.__class__
属性创建Bar __metaclass__
(而不是type()
),那么子类将不会继承该行为。“但我并不完全理解这一点。
答案 0 :(得分:3)
在第二种情况下,不是返回元类的实例而是实际返回type
的实例,而是依次设置新创建的类{{1}的__class__
属性而E
代替<type 'type'>
。因此,as per the rule 2 Python检查基类的D
属性(或__class__
或type(E)
)并决定使用E.__class__
作为type
该元类,因此在这种情况下永远不会调用F
&#39; s D
。
__new__
存在,则使用它。dict['__metaclass__']
属性,如果未找到,则使用其类型)。因此,正确的方法是在元类的__class__
方法中调用类型__new__
方法:
__new__
<强>输出:强>
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.__new__(cls, name, bases, dct)
class E(object):
__metaclass__ = D
class F(E): pass
class A(object):
pass