【发布时间】:2011-04-05 08:23:13
【问题描述】:
我想为类定义属性,并且能够在我实际实例化该类的对象之前访问它们。
我会给出一些背景信息。我的应用程序处理一个组件库。每个组件都映射到一个 Python 类。现在我想在实际实例化类之前知道组件需要什么配置。
一种解决方案是这样写:
class Component:
@classmethod
def config(cls, name, description, default=None):
''' Define one configuration switch for the class. '''
# now put this information in a class-specific dictionary
class Model1(Component):
@classmethod
def define_configuration(cls):
cls.config('n', 'number of burzs to instigate')
cls.config('skip', 'skip any barzs among the burzs', default=True)
# ...
component_class = Model1
component_class.define_configuration()
但是,它看起来很丑陋。理想情况下,我希望能够编写如下内容,并且仍然能够将配置开关放在特定于类的字典中以供以后访问。
class Model1(Component):
config('n', 'number of burz to instigate')
config('skip', 'skip any barz in the data', default=True)
我最初的解决方案是这样写:
class Model1(Component):
Model1.config('n', 'number of burz to instigate')
Model1.config('skip', 'skip any barz in the data', default=True)
但是我在 SO 上的其他问题上发现,执行主体时尚未定义类名。
我该怎么办?
tl;dr:我怎样才能获得一个很好的语法来定义特定于类的属性(在我实例化该类的对象之前)?
这是(作为记录)建议的解决方案(有点详细)。 耶!我可以得到我想要的。 :-)
from collections import namedtuple
Config = namedtuple('Config', 'name desc default')
def config(name, description, default=None):
ComponentMeta.tmp_config_storage.append(Config(name, description, default))
class ComponentMeta(type):
tmp_config_storage = []
def __init__(cls, clsname, bases, clsdict):
for config in ComponentMeta.tmp_config_storage:
if not 'my_config' in cls.__dict__:
setattr(cls, 'my_config', [])
cls.my_config.append(config)
ComponentMeta.tmp_config_storage = []
class Component(object):
__metaclass__ = ComponentMeta
class Model1(Component):
config('x1', 'for model1')
config('y1', 'for model1')
class Model2(Component):
config('x2', 'for model2')
print 'config for Model1:', Model1.my_config
print 'config for Model2:', Model2.my_config
【问题讨论】:
-
我很确定您需要在其中某处使用
self。但我不明白你为什么对 config 方法使用两次调用? -
@vlad 他使用了两个调用,因为他想添加两个项目。每个电话加一个。此外,您看到的是
cls而不是self,因为这些是在类而不是实例上操作的类方法。 -
哦。我现在明白他对“特定类别词典”的意思了。
-
您可能希望将检查
if not 'my_config' in cls.__dict__移动到for循环之前,这样它就不会每次都执行。
标签: python class metaprogramming