这就是我的意思:
>>> class Foo:
pass
>>> foo = Foo()
>>> setattr(foo, "@%#$%", 10)
>>> foo.@%#$%
SyntaxError: invalid syntax
>>> getattr(foo, "@%#$%")
10
>>> foo.__dict__
{'@%#$%': 10}
Run Code Online (Sandbox Code Playgroud)
我查了一下,它在 python 2 的问题跟踪器上出现了两次:
https://bugs.python.org/issue14029
https://bugs.python.org/issue25205
一次是 Python 3:
https://bugs.python.org/issue35105
他们坚持认为这不是错误。然而,这种行为显然不是故意的。它没有记录在任何版本中。对此有何解释?这似乎是很容易被忽略的东西,但这感觉就像把它扫到地毯下一样。那么,setattr
的行为背后是否有任何原因,或者它只是 python 的一种良性特质?
一个错误的东西当它不出现这种情况应该发生的,也就是说,当有禁止其通信的一些方法。如果没有文档说明这不应该发生,那么(最坏的情况)这是一种特质,而不是错误。
Python 文档中似乎没有任何内容禁止不能与点表示法一起使用的属性名称(毕竟,这只是语法糖),例如foo.@%#$%
. 唯一提到的是它们等效的示例,特别是:
例如,
setattr(x, 'foobar', 123)
相当于x.foobar = 123
。
唯一的限制似乎是类本身是否允许它:
如果对象允许,该函数将值分配给属性。
在更正式的意义上,点符号在此处指定:
6.3.1. 属性引用
属性引用是一个primary,后跟一个句点和一个名称:
attributeref ::= primary "." identifier
。该
primary
结果必须为类型支持属性引用,其中大部分物体做的一个目的。然后要求此对象生成名称为 的属性identifier
。可以通过覆盖该__getattr__()
方法来定制此生产。
请注意,identifier
在该语法中,根据此处,它具有超出实际属性名称的限制,并且PEP 3131更详细地了解了允许的内容(正是 PEP 将标识符移到了非 ASCII 世界)。
由于标识符的限制比字符串中允许的限制更严格,因此getattr/setattr
属性名称可以是点符号中允许的名称的超集是有道理的。
归档时间: |
|
查看次数: |
90 次 |
最近记录: |