python 动态创建类属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2583620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamically create class attributes
提问by xyz-123
I need to dynamically create class attributes from a DEFAULTS dictionary.
我需要从 DEFAULTS 字典动态创建类属性。
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], ...)
I could also achive this by having sth. like __init__
for class creation, in order to dynamically create these attributes from dictionary and save a lot of code and stupid work.
我也可以通过某种方式实现这一目标。就像__init__
创建类一样,为了从字典中动态创建这些属性并节省大量代码和愚蠢的工作。
How would you do this?
你会怎么做?
Thank you very much in advance!
非常感谢您提前!
回答by nkrkv
You could do it without metaclasses using decorators. This way is a bit more clear IMO:
您可以使用装饰器在没有元类的情况下做到这一点。这种方式更清晰一点 IMO:
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
Prior to Python 2.6 class decorators were unavailable. So you can write:
在 Python 2.6 之前,类装饰器不可用。所以你可以写:
class Settings(object):
pass
Settings = apply_defaults(Settings)
in older versions of python.
在旧版本的python中。
In the provided example apply_defaults
is reusable… Well, except that the defaults are hard-coded in the decorator's body :) If you have just a single case you can even simplify your code to this:
在提供的示例中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, ...))
This is possible since classes (in the sense of types) are objects themselves in Python.
这是可能的,因为类(在类型的意义上)是 Python 中的对象本身。
回答by ?ukasz
I think that's case for metaclass:
我认为元类就是这种情况:
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
回答by Brian
When defining a class, the local namespace will be converted into the class namespace at the conclusion of the class body. As such, you can accomplish this with:
定义类时,本地命名空间将在类主体结束时转换为类命名空间。因此,您可以通过以下方式完成此操作:
class Settings(object):
for key, val in defaults.iteritems():
locals()[key] = some_complex_init_function(val, ...)