Python中的属性访问语法存在限制(至少在CPython 2.7.2实现中):
>>> class C(object): pass
>>> o = C()
>>> o.x = 123 # Works
>>> o.if = 123
o.if = 123
^
SyntaxError: invalid syntax
我的问题有两个:
o.if = 123
中)的根本原因?在我的某个程序中执行o.class = …
是有意义的,我对它无法做到有点失望(o.class_
会起作用,但看起来并不那么简单)。
PS :问题显然是if
和class
是Python关键字。问题是为什么使用关键字作为属性名称将被禁止(我没有看到表达式o.class = 123
中有任何歧义),以及这是否记录。
答案 0 :(得分:8)
因为当关键字总是关键字而不是上下文时,解析器更简单(例如if
在语句级别时是一个关键字,而在表达式中只是一个标识符 - 对于if
它来说由于X if C else Y
而加倍,并且for
用于列表推导和生成器表达式。)
因此,代码甚至没有达到属性访问的程度,它只是被解析器拒绝,就像错误的缩进一样(这就是为什么它是SyntaxError
而不是AttributeError
或者东西)。它不区分您是使用if
作为属性名称,变量名称,函数名称还是类型名称。它永远不会是一个标识符,只是因为解析器总是为它分配“关键字”标签并使其成为与标识符不同的标记。
在大多数语言中都是一样的,语言语法(+ lexer规范)就是这方面的文档。 Language spec mentions it explicitly。它在Python 3中也没有变化。
另外,仅仅因为您可以使用setattr
或__dict__
制作带有保留名称的属性,并不意味着应该。不要强迫自己/ API用户使用getattr
而不是自然属性访问。当需要访问变量属性名称时,应保留getattr
。
答案 1 :(得分:1)
因为if
是关键字。您对o.while
和o.for
:
pax> python
>>> class C(object): pass
...
>>> o = C()
>>> o.not_a_keyword = 123
>>> o.if = 123
File "<stdin>", line 1
o.if = 123
^
SyntaxError: invalid syntax
>>> o.while = 123
File "<stdin>", line 1
o.while = 123
^
SyntaxError: invalid syntax
>>> o.for = 123
File "<stdin>", line 1
o.for = 123
^
SyntaxError: invalid syntax
Python中的其他关键字可以通过以下方式获得:
>>> import keyword
>>> keyword.kwlist
['and', 'as', 'assert', 'break', 'class', 'continue', 'def',
'del', 'elif', 'else', 'except', 'exec', 'finally', 'for',
'from', 'global', 'if', 'import', 'in', 'is', 'lambda',
'not', 'or', 'pass', 'print', 'raise', 'return', 'try',
'while', 'with', 'yield']
你应该不通常在Python中使用关键字作为变量名。
我建议选择一个更具描述性的名称,例如iface
如果是界面,或infld
表示输入字段,等等。
至于你的问题编辑为什么不允许关键字,如果词汇元素没有上下文,它会极大地简化解析器。必须在某些地方将词法标记if
视为关键字而在其他地方将标识符视为其他标识符,如果您更明智地选择标识符,则会引入并非真正需要的复杂性。
例如,C ++语句:
long int int = char[new - int];
可以(有点困难)使用复杂的解析器进行评估,该解析器基于这些词法元素出现的位置(以及它们两侧存在的内容)。但是,(至少部分地)为了简单(和可读性),这没有做到。