按类型创建的类的python元类
Posted
技术标签:
【中文标题】按类型创建的类的python元类【英文标题】:python metaclasses of classes created by type 【发布时间】:2013-05-16 10:28:40 【问题描述】:这里的代码胜过文字:
class MetaA(type):
def __new__(cls, name, bases, attrs):
print "MetaA"
return super(MetaA, cls).__new__(cls, name, bases, attrs)
class A(object):
__metaclass__ = MetaA
这将打印MetaA
class MetaB(MetaA):
def __new__(cls, name, bases, attrs):
print "MetaB"
return super(MetaB, cls).__new__(cls, name, bases, attrs)
B = type('B', (A, ), '__metaclass__': MetaB)
这将再次打印MetaA
(?!)
我希望:
MetaB
MataA
问题是:
-
为什么我只收到
MetaA
?
如何更改代码获取:
MetaB
MataA
【问题讨论】:
【参考方案1】:原因是type(name, bases, dict)
不是创建具有指定元类的类的正确方法。
解释器实际上避免在看到__metaclass__
属性定义并调用mateclass 而不是 type(name, bases, dict)
时调用type(name, bases, dict)
,因为它通常会这样做。
这里是相关的docs section 解释它:
读取类定义时,如果定义了__元类__则 分配给它的可调用对象将被调用而不是 type()。这 允许编写类或函数来监视或更改 类创建过程 [...]
如果你像这样修改你的代码:
class MetaA(type):
def __new__(cls, name, bases, attrs):
print "MetaA"
return super(MetaA, cls).__new__(cls, name, bases, attrs)
class A(object):
__metaclass__ = MetaA
class MetaB(MetaA):
def __new__(cls, name, bases, attrs):
print "MetaB"
return super(MetaB, cls).__new__(cls, name, bases, attrs)
class B(A):
__metaclass__ = MetaB
...然后你会得到预期的输出:
MetaA
MetaB
MetaA
(创建A类时打印第一行,创建B类时打印第二行和第三行)
更新:该问题假定类 B
的动态创建,所以我将扩展我的答案。
要使用 metacalss 动态构造 B
类,您应该做与解释器相同的事情,即使用 __metaclass__
instad of type(name, bases, dict)
中的元类构造类。
像这样:
B = MetaB('B', (A, ), '__metaclass__': MetaB)
【讨论】:
你说对了一部分,但你没有抓住重点。我使用“类型”的原因是因为我有很多想要动态创建的类。但是由于 'type' 是元类,应该写 MetaB('B', (A, ), 'metaclass': MetaB) 而不是 type('B', (A, ), ' 元类':元B)。我昨天已经想通了。如果您更改答案以反映我的要求(动态创建的类),我会接受您的回答。 @mnowotka 啊,明白了。这就是您首先使用type
的原因。我已经更新了答案。以上是关于按类型创建的类的python元类的主要内容,如果未能解决你的问题,请参考以下文章