属性不是有效的python标识符

wim*_*wim 8 python attributes

通常的属性访问方法要求属性名称是有效的python标识符.

但属性不必是有效的python标识符:

>>> class Thing:
...     def __init__(self):
...         setattr(self, '0potato', 123)
...         
>>> t = Thing()
>>> Thing.__getattribute__(t, '0potato')
123
>>> getattr(t, '0potato')
123
Run Code Online (Sandbox Code Playgroud)

当然,t.0potato仍然是一个SyntaxError,但属性仍然存在:

>>> vars(t)
{'0potato': 123}
Run Code Online (Sandbox Code Playgroud)

这是允许的原因是什么?对于带有空格,空字符串,python保留关键字等的属性,是否真的有任何有效的用例?我认为原因是属性只是对象/命名空间dict中的键,但这没有意义,因为不允许使用其他有效dict键的对象:

>>> setattr(t, ('tuple',), 321)
TypeError: attribute name must be string, not 'tuple'
Run Code Online (Sandbox Code Playgroud)

wim*_*wim 2

帖子评论中的详细信息完全回答了这个问题,所以我将其发布为答案:

吉多说:

...这是一个可以通过 getattr() 和 setattr() 使用任意字符串的功能。然而,这些函数应该(并且确实!)拒绝非字符串。

可能的用例包括隐藏常规点访问的属性,以及使属性与外部数据源相对应(这可能与 Python 关键字冲突)。因此,争论似乎是根本没有充分的理由禁止它。

至于禁止非字符串的原因,这似乎是一个合理的限制,可以确保实现更高的性能:

尽管Python的字典已经有一些仅限字符串的优化——一旦第一个非键字符串出现,它们只是动态地适应更通用且稍慢的方法。