使用元类访问子类的静态属性
Using metaclass to access static attributes of subclass
考虑以下代码:
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 sub 类(C 和 D) 上调用函数 print_name 并打印出来静态属性 name。所以所需的输出应该是这样的 -
animal
zebra
pig
非常感谢!
在你的 print_name()
函数中,你应该替换这个:
return type.__new__( *args, **kwargs)
有了这个:
return cls
这样你就可以摆脱你看到的TypeError
。
发生错误是因为 __new__
的第一个参数必须是类型对象。 __new__
的正确调用是:type.__new__(type, *args, **kwargs)
,但在您的情况下,确实不需要两次创建 class。
现在,即使有了这个修复,您也不会在输出中看到 'zebra' 和 'pig',因为您直接从 class B
type
,这样你的元class信息就丢失了。
你应该考虑这样的事情:
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
及其所有子class 类型都将是 print_name
,每次子class 时您的代码都会正确执行已创建。
(附带说明,metaclasses 可能会导致无法使用多重继承,因此请仔细考虑您是否真的需要它们。)
考虑以下代码:
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 sub 类(C 和 D) 上调用函数 print_name 并打印出来静态属性 name。所以所需的输出应该是这样的 -
animal
zebra
pig
非常感谢!
在你的 print_name()
函数中,你应该替换这个:
return type.__new__( *args, **kwargs)
有了这个:
return cls
这样你就可以摆脱你看到的TypeError
。
发生错误是因为 __new__
的第一个参数必须是类型对象。 __new__
的正确调用是:type.__new__(type, *args, **kwargs)
,但在您的情况下,确实不需要两次创建 class。
现在,即使有了这个修复,您也不会在输出中看到 'zebra' 和 'pig',因为您直接从 class B
type
,这样你的元class信息就丢失了。
你应该考虑这样的事情:
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
及其所有子class 类型都将是 print_name
,每次子class 时您的代码都会正确执行已创建。
(附带说明,metaclasses 可能会导致无法使用多重继承,因此请仔细考虑您是否真的需要它们。)