我想为类定义属性,并且能够在实际实例化该类的对象之前访问它们。在
我会给你一些背景。我的应用程序处理一个组件库。每个组件都映射到一个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()
不过,它看起来很难看。理想情况下,我希望能够编写如下内容,并且仍然能够将配置开关放在类特定的字典中以便以后访问。在
^{pr2}$我最初的解决方案是写一些类似于:
^{3}$然而,我在这里发现了其他问题,因此在执行body时类名还没有定义。在
我该怎么办?在
太长了,读不下去了?在这是(记录在案)提出的解决方案(有点详细)。 耶!我可以得到我想要的东西。:-)
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
一旦执行了主体,就定义了类名。当导入包含类的文件时会发生这种情况。这与创建类的实例不同。在
这种方法不符合你的目的吗?类配置可以存储在类变量中,可以在实例化该类的任何对象之前修改和添加该变量。在
使用类变量应该符合您的目的。在
为什么不简单点,比如说:
只要
config
函数返回isaconfig
函数可以识别的对象,并且addconfigtodict
函数可以以任何格式正确地设置到特殊字典中,那么您就完蛋了。在如果我正确地理解了您的规范,您就不希望使用
Model1.skip
这样的普通属性,对吗?这就是为什么我在makeconfigdict
中使用delattr
调用(也是为什么我在类的字典上使用.items()
因为字典在循环过程中被修改,所以最好使用.items()
,它获取所有名称和值的“快照”列表,而不是通常的.iteritems()
,后者只是在字典上迭代,因此,不允许使用在循环过程中修改)。在更正
这是通过使config成为一个外部函数来将项添加到
ComponentMeta.config_instances
。ComponentMeta
然后在创建一个类时检查这个列表,并对项目调用config_item
。请注意,这不是线程安全的(尽管我可以这样做)。另外,如果ComponentMeta
的子类未能调用super
或空ComponentMeta.config_items
,则下一个创建的类将获得配置项。在相关问题 更多 >
编程相关推荐