要创建动态类变量,您似乎有两个选项 - 使用locals()
或__metaclass__
。我不是分配给locals()
的粉丝,但它似乎在一个类定义中工作,并且比它的__metaclass__
替代更简洁。
以这种方式使用locals()
是否可靠?两种解决方案的优点/缺点是什么?
meta_attrs = ["alpha", "beta", "gamma"]
class C(object):
local_context = locals()
for attr in meta_attrs:
local_context[attr] = attr.upper()
class D(object):
class __metaclass__(type):
def __new__(mcs, name, bases, attrs):
for attr in meta_attrs:
attrs[attr] = attr.upper()
return type.__new__(mcs, name, bases, attrs)
if __name__ == '__main__':
print C.alpha, C.beta, C.gamma
print D.alpha, D.beta, D.gamma
答案 0 :(得分:4)
正如kindall所提到的,类装饰器是第三种选择:
meta_attrs = ["alpha", "beta", "gamma"]
def decorate(klass):
for attr in meta_attrs:
setattr(klass, attr, attr.upper())
return klass
@decorate
class C(object):
pass
这是第四个选项:
meta_attrs = ["alpha", "beta", "gamma"]
class C(object):
pass
for attr in meta_attrs:
setattr(C, attr, attr.upper())
我自己会选择第五个选项:没有动态类属性。我看不到用例。如果我真的需要它,我可能会使用第四个选项,除非我需要多个类,然后我会使用装饰器。
元类通常过于复杂,locals()
黑客真的只是一个丑陋的伎俩,应该避免。
答案 1 :(得分:1)
__metaclass__
可以是任何可调用的:
class D(object):
def __metaclass__(name, bases, dct):
for attr in meta_attrs:
dct[attr] = attr.upper()
return type(name, bases, dct)
这几乎与locals()
方法一样简洁,并且不依赖于CPython实现细节。