How to use dot notation for dict in python?
我对python非常陌生,我希望我可以用
假设我有一个这样的
1 2 3 4 | >>> test = dict() >>> test['name'] = 'value' >>> print(test['name']) value |
但我希望我能做
1 2 3 4 5 6 7 8 9 10 | class JuspayObject: def __init__(self,response): self.__dict__['_response'] = response def __getattr__(self,key): try: return self._response[key] except KeyError,err: sys.stderr.write('Sorry no key matches') |
这是可行的!当我这样做的时候:
1 | test.name // I get value. |
但问题是,当我单独打印
1 | 'Sorry no key matches' |
为什么会这样?
这个功能已经存在于标准库中,所以我建议您只使用它们的类。
1 2 3 4 5 6 7 | >>> from types import SimpleNamespace >>> d = {'key1': 'value1', 'key2': 'value2'} >>> n = SimpleNamespace(**d) >>> print(n) namespace(key1='value1', key2='value2') >>> n.key2 'value2' |
添加、修改和删除值是通过常规属性访问实现的,也就是说,您可以使用诸如
再次回到听写:
1 2 | >>> vars(n) {'key1': 'value1', 'key2': 'value2'} |
dict中的键应该是字符串标识符,以便属性访问正常工作。
在python 3.3中添加了简单的名称空间。对于旧版本的语言,
我假设您对JavaScript很熟悉,并且希望借用这种语法…我可以根据个人经验告诉你,这不是一个好主意。
它看起来确实不那么冗长和整洁;但从长远来看,它只是模糊的。dict是dict,试图让它们像具有属性的对象一样工作可能会导致(坏的)意外。
如果您需要像处理字典一样处理对象的字段,那么在需要时,您可以始终使用内部
但是通过阅读你的例子,你似乎在尝试一些不同的东西…因为点运算符已经在没有任何额外代码的情况下查找
当所有其他属性查找规则都失败时,使用
附带说明:普通属性访问不使用
1 2 3 4 5 6 7 8 9 10 11 | class JuspayObject: def __init__(self,response): # don't use self.__dict__ here self._response = response def __getattr__(self,key): try: return self._response[key] except KeyError,err: raise AttributeError(key) |
现在,如果您的类没有其他的职责(并且您的Python版本大于等于2.6,并且您不需要支持旧版本),您可以只使用一个namedtuple:http://docs.python.org/2/library/collections.html collections.namedtuple
你能用一个命名的元组吗?
1 2 3 4 5 | from collections import namedtuple Test = namedtuple('Test', 'name foo bar') my_test = Test('value', 'foo_val', 'bar_val') print(my_test) print(my_test.name) |
使用
尝试这样的方法…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class JuspayObject: def __init__(self,response): self.__dict__['_response'] = response def __getattr__(self, key): # First, try to return from _response try: return self.__dict__['_response'][key] except KeyError: pass # If that fails, return default behavior so we don't break Python try: return self.__dict__[key] except KeyError: raise AttributeError, key >>> j = JuspayObject({'foo': 'bar'}) >>> j.foo 'bar' >>> j <__main__.JuspayObject instance at 0x7fbdd55965f0> |
除此之外,还可以添加对嵌套dict的支持:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | from types import SimpleNamespace class NestedNamespace(SimpleNamespace): def __init__(self, dictionary, **kwargs): super().__init__(**kwargs) for key, value in dictionary.items(): if isinstance(value, dict): self.__setattr__(key, NestedNamespace(value)) else: self.__setattr__(key, value) nested_namespace = NestedNamespace({ 'parent': { 'child': { 'grandchild': 'value' } }, 'normal_key': 'normal value', }) print(nested_namespace.parent.child.grandchild) # value print(nested_namespace.normal_key) # normal value |
向类中添加
1 | print text |
更多信息请访问:http://www.diveintopython.net/object-oriented-framework/special-class-methods2.html