字典-如何在Python中为字典使用点表示法?
我是python的新手,我希望可以做test表示法来访问value的值。
可以说我有test这样:
>>> test = dict()
>>> test['name'] = 'value'
>>> print(test['name'])
value
但我希望我能做test来获得value。实际上,我是通过重写类中的__getattr__方法来做到这一点的:
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')
这有效! 当我做:
test.name // I get value.
但是问题是,当我仅单独打印test时,出现以下错误:
'Sorry no key matches'
为什么会这样呢?
7个解决方案
83 votes
标准库中已经存在此功能,因此我建议您只使用它们的类。
>>> from types import SimpleNamespace
>>> d = {'key1': 'value1', 'key2': 'value2'}
>>> n = SimpleNamespace(**d)
>>> print(n)
namespace(key1='value1', key2='value2')
>>> n.key2
'value2'
可以通过常规属性访问来添加,修改和删除值,即可以使用诸如argparse.Namespace和del n.key之类的语句。
要再次返回字典:
>>> vars(n)
{'key1': 'value1', 'key2': 'value2'}
字典中的键应该是字符串标识符,以便属性访问才能正常工作。
在Python 3.3中添加了简单的名称空间。 对于较旧的语言版本,argparse.Namespace具有类似的行为。
wim answered 2020-02-04T13:11:53Z
29 votes
我假设您熟悉Java语言,并且想借用这种语法...我可以凭个人经验告诉您,这不是一个好主意。
它看起来确实不那么冗长和整洁。 但从长远来看,它只是晦涩难懂。 字典是字典,试图使它们的行为像带有属性的对象一样,可能会导致(严重)意外。
如果您需要像处理字典一样操作对象的字段,则始终可以在需要时使用内部__dict__属性,这样就可以清楚地知道自己在做什么。 或者也可以使用getattr(obj, 'key')考虑继承结构和类属性。
但是通过阅读示例,您似乎正在尝试一些不同的方法...点运算符已经可以在__dict__属性中查找,而无需任何其他代码。
fortran answered 2020-02-04T13:12:27Z
5 votes
您可以使用一个命名的元组吗?
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)
Yann answered 2020-02-04T13:12:47Z
4 votes
当所有其他属性查找规则均失败时,将self.__dict__用作后备。 当您尝试“打印”对象时,Python会寻找__repr__方法,由于您没有在类中实现它,所以最终会调用__getattr__(是的,在Python方法中也是属性)。 您不应该假设将使用哪个键getattr调用,最重要的是,如果__getattr__无法解析key,则必须引发AttributeError。
附带说明:不要将self.__dict__用于普通属性访问,而应使用普通属性表示法:
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]
bruno desthuilliers answered 2020-02-04T13:13:18Z
2 votes
使用__getattr__时必须小心,因为它用于许多内置的Python功能。
试试这样的东西...
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>
Aya answered 2020-02-04T13:13:42Z
2 votes
除了这个答案之外,还可以添加对嵌套字典的支持:
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
请注意,对于例如 列表。
Michael H. answered 2020-02-04T13:14:07Z
0 votes
向类中添加__repr__()方法,以便您可以自定义要在其上显示的文本
print text
在此处了解更多信息:[https://web.archive.org/web/20121022015531/http://diveintopython.net/object_directional_framework/special_class_methods2.html]
Makyen answered 2020-02-04T13:14:31Z