天天看点

python中的点表示什么_字典-如何在Python中为字典使用点表示法?

字典-如何在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