动态创建类属性
我需要根据一个默认的字典动态创建类的属性。
defaults = {
'default_value1':True,
'default_value2':True,
'default_value3':True,
}
class Settings(object):
default_value1 = some_complex_init_function(defaults[default_value1], ...)
default_value2 = some_complex_init_function(defaults[default_value2], ...)
default_value3 = some_complex_init_function(defaults[default_value3], ...)
我也可以通过类似于 __init__
的方法来创建类,这样就能从字典中动态生成这些属性,这样可以省去很多代码和无聊的工作。
你会怎么做呢?
非常感谢你的帮助!
3 个回答
2
在定义一个类的时候,类里面的局部命名空间会在类的主体结束时变成类的命名空间。简单来说,就是你在类里定义的东西,最后会被整理成这个类的一部分。你可以用下面的方式来实现:
class Settings(object):
for key, val in defaults.iteritems():
locals()[key] = some_complex_init_function(val, ...)
5
我觉得这就是元类的情况:
class SettingsMeta(type):
def __new__(cls, name, bases, dct):
for name, value in defaults.items():
dct[name] = some_complex_init_function(value, ...)
return type.__new__(cls, name, bases, dct)
class Settings(object):
__metaclass__ = SettingsMeta
32
你可以不使用 metaclasses,而是用装饰器来实现。这种方法在我看来更清晰一些:
def apply_defaults(cls):
defaults = {
'default_value1':True,
'default_value2':True,
'default_value3':True,
}
for name, value in defaults.items():
setattr(cls, name, some_complex_init_function(value, ...))
return cls
@apply_defaults
class Settings(object):
pass
在 Python 2.6 之前,类装饰器是不可用的。所以你可以在:
class Settings(object):
pass
Settings = apply_defaults(Settings)
较早版本的 Python 中这样写。
在这个例子中,apply_defaults
是可以重复使用的……不过,默认值是写死在装饰器里的 :) 如果你只有一个情况,甚至可以把代码简化成这样:
defaults = {
'default_value1':True,
'default_value2':True,
'default_value3':True,
}
class Settings(object):
"""Your implementation goes here as usual"""
for name, value in defaults.items():
setattr(Settings, name, some_complex_init_function(value, ...))
这是可能的,因为在 Python 中,类(作为类型的意思)本身就是对象。