我需要定义一些键值参数来配置类的行为。我的要求是两个:
第一个要求的自然方法是使用dict
(因此我可以使用for
循环遍历键,值或项目),但对于第二个要求,似乎更合适使用类层次结构,并让属性查找机制完成工作(另外我得到其他好东西,比如能够使用某些值的属性)。
有没有办法让两全其美?
阅读注释后,它不需要是可变的(我不会更改已经创建的实例的值),它只是用于静态配置。但我可能需要在更具体的实例中添加新值。
我认为最后我可以使用dict.copy
+ dict.update
来表示特定的实例(我可以没有属性)。
答案 0 :(得分:2)
在某种程度上,就像Fabio在文章中提出的那样,我会注意到两者并不相互排斥,因为在Python中[几乎]所有东西都是一个对象(包括类!)。
一个明显的解决方案是 - 再次引用Fabio - 继承dict
。另一个是从collections.abc
containers开始创建自己的类(使用abstract base class(abc
)不是必需的,但可能是从头开始实现自己的容器的最pythonic方式)。
HTH!
答案 1 :(得分:1)
这就是你需要的吗?
class my_dict(dict):
def __getattr__(self, name):
return self[name]
def __setattr__(self, name, value):
self[name] = value
d = my_dict()
d.key = "value"
print d.key #>>>value
for k,v in d.items():
print k,v #>>>key value
答案 2 :(得分:1)
如果你可以使用python 3.3 ChainMap正是你想要的。
http://docs.python.org/3.3/library/collections#collections.ChainMap
它基本上是一个字典列表,并会在每个字典中按顺序查找给定的键,直到找到匹配项。
实际上,这是在2.7中使用它的代码:
http://code.activestate.com/recipes/305268-chained-map-lookups/
答案 3 :(得分:0)
您可以使用named tuples。请参阅here以及此question上接受的答案,以获得对它们的精彩介绍。该答案的一些重点是:
它们是在Python 2.6和Python 3.0中添加的,尽管在Python 2.4中有一个recipe用于实现。
命名元组向后兼容正常元组
此外,命名元组有许多有用的方法,例如_fields
来获取已使用的名称,以及_asdict
方法返回命名元组的(有序)dict
内容。
答案 4 :(得分:0)
这是我的看法:
class Config(object):
def _keys(self):
return (name for name in dir(self) if not name.startswith('_'))
__iter__ = _keys
def _values(self):
return (getattr(self, name) for name in self)
def _items(self):
return ((name, getattr(self, name)) for name in self)
>>> class Foo(Config):
... bar = 3
... baz = 'spam'
...
>>> class Sub(Foo):
... bar = 4
...
>>> x = Sub()
>>> list(x._items())
[('bar', 4), ('baz', 'spam')]
>>>