考虑以下代码:
def print_name(*args, **kwargs):
cls = type(*args, **kwargs)
print "hello " + cls.name
return type.__new__( *args, **kwargs)
class B(object):
__metaclass__ = print_name
name = 'animal'
class C(B):
name = "zebra"
class D(B):
name = "pig"
我想要实现的是在B子类(C和D)上调用函数 print_name 并使其打印静态属性 name 。所以期望的输出应该如下所示 -
animal
zebra
pig
非常感谢!
答案 0 :(得分:2)
在print_name()
函数中,您应该替换它:
return type.__new__( *args, **kwargs)
用这个:
return cls
这样你就可以摆脱你所看到的TypeError
。
发生错误是因为__new__
的第一个参数必须是类型对象。 __new__
的正确调用是:type.__new__(type, *args, **kwargs)
,但在您的情况下,确实没有必要两次创建类。
现在,即使使用此修复程序,您也不会在输出中看到'zebra'和'pig',因为您直接从B
生成了类type
,因此您的元类信息丢失了。
你应该考虑这样的事情:
class print_name(type):
def __new__(mcls, *args, **kwargs):
cls = super(print_name, mcls).__new__(mcls, *args, **kwargs)
print "hello " + cls.name
return cls
这样,B
及其所有子类的类型为print_name
,每次创建子类时都会正确执行代码。
(作为旁注,元类可能使得无法使用多重继承,因此请仔细考虑是否真的需要它们。)