programattically定义的类定义属性
我有一个为应用程序保持不变数据库值对象,它看起来像某事,这一小撮:programattically定义的类定义属性
class TestObject(object):
"""reflects constants in _test_object"""
_pairs = (
(1 , 'A'),
(2 , 'B'),
(4 , 'C'),
(8 , 'D'),
)
mapping = setup(_pairs)
的mapping
函数创建一个字典,让我的AK,v和v,k查找基于_pairs
。它们都以“id,name”的形式出现。
为了使事情的应用程序更容易,我经常设置“文本值”作为一个属性,以及:
class TestObject(object):
...
...
A = 1
B = 2
C = 4
D = 8
虽然这使得使用类的真的很棒,这是一个有点笨拙到重新输入这一切,并保持同步。另外,我必须编写单元测试以确保属性与_pairs中的正确ID匹配。
我一直试图围绕一种方式来包装我的头,以避免写出来,并自动填充每个TestObject类与应用程序启动时的属性。
我知道我可以覆盖这个类并让它检查_pairs/mapping attibute以进行故障转移,但是我真的很感兴趣,是否有可能根据需要将程序填充到类中。目前还没有__class__
,因为该类还没有定义。
仅仅是明确的,我想要做的东西的种类是沿此线:
class NotValidPython():
_pairs = ((1,'A'),)
for (k,v) in _pairs:
setattr(__class__, v, k)
使用装饰:
def dynamic_attrs(cls):
for v, k in getattr(cls, '_pairs', []):
setattr(cls, k, v)
# you also optionally delete the _pairs attr here using del cls._pairs
return cls
@dynamic_attrs
class TestObject(object):
"""reflects constants in _test_object"""
_pairs = (
(1 , 'A'),
(2 , 'B'),
(4 , 'C'),
(8 , 'D'),
)
一个元可以用于此目的。您可以覆盖元类中的__new__
,然后填充属性字典或覆盖__init__
,然后覆盖属性字典或使用setattr
设置类对象本身的属性。
使用__new__
:
class Meta(type):
def __new__(meta, clsname, bases, dct):
dct.update(dict((k, v) for v, k in dct.pop('_pairs')))
return type.__new__(meta, clsname, bases, dct)
class TestObject(object):
__metaclass__ = Meta
"""reflects constants in _test_object"""
_pairs = (
(1 , 'A'),
(2 , 'B'),
(4 , 'C'),
(8 , 'D'),
)
使用__init__
:
class Meta(type):
def __init__(cls, clsname, bases, dct):
attrs = dct.pop('_pairs')
for v, k in attrs:
setattr(cls, k, v)
因此,这是辉煌的,但它无法正常工作 - 是为了我的需要。如果我有'AnotherTestObject',其值((1,'F'),(2,'G'),...)所有数据都在元类的字典中,所以碰撞和属性是不是普通班的本地人。 –
@JonathanVanasco对不起,我不明白你在这里意味着什么,碰撞是什么意思? –
看看这个要点 - https://gist.github.com/jvanasco/9141157说明命名空间冲突。因为K/V存储在元类而不是类中,所以你只能对一个类使用'Meta'。如果另一个使用'Meta'的类具有'A'值,它将覆盖所有先前的'A'值;如果另一个类提供'Z'值,它将使'Z'对所有其他类可用。 –
无需使用元类。只要把你的代码相同的模块作为类定义,但外类定义:
class TestClass():
_pairs = ((1,'A'),)
for (k, v) in TestClass._pairs:
setattr(TestClass, v, k)
这种方法的问题是我需要识别所有适用的类;这就是为什么我想将它整合到类定义中。 –
在这种情况下,我可能会用@ F.J的答案。 – bdesham
哇。辉煌!非常感谢。 –