为什么属性名称不能是 Python 关键字?

2022-01-13 00:00:00 python attributes syntax-error

问题描述

在 Python 中(至少在 CPython 2.7.2 实现中)对属性访问的语法有限制:

There is a restriction on the syntax of attribute access, in Python (at least in the CPython 2.7.2 implementation):

>>> class C(object): pass
>>> o = C()
>>> o.x = 123  # Works
>>> o.if = 123
    o.if = 123
       ^
SyntaxError: invalid syntax

我的问题有两个:

  1. 禁止使用 Python 关键字属性名称(如 o.if = 123)是否有根本原因?
  2. 是否/在哪里记录了上述对属性名称的限制?

在我的一个程序中执行 o.class = ... 是有意义的,但我对无法执行此操作有点失望(o.class_code> 会起作用,但看起来并不简单).

It would make sense to do o.class = …, in one of my programs, and I am a little disappointed to not be able to do it (o.class_ would work, but it does not look as simple).

PS:问题显然是ifclass是Python关键字.问题是 why 禁止使用关键字作为属性名称(我在表达式 o.class = 123 中没有看到任何歧义),以及这是否是 记录在案.

PS: The problem is obviously that if and class are Python keywords. The question is why using keywords as attribute names would be forbidden (I don't see any ambiguity in the expression o.class = 123), and whether this is documented.


解决方案

因为当关键字总是关键字而不是上下文时解析器更简单(例如,if 在语句级别时是关键字,但是只是在表达式中的标识符 - 对于 if 它会是双重困难,因为 X if C else Y,并且 for 用于列表推导式和生成器表达式).

Because parser is simpler when keywords are always keywords, and not contextual (e.g. if is a keyword when on the statement level, but just an identifier when inside an expression — for if it'd be double hard because of X if C else Y, and for is used in list comprehensions and generator expressions).

所以代码甚至没有到达属性访问的地步,它只是被解析器拒绝,就像不正确的缩进一样(这就是为什么它是 SyntaxError,而不是 AttributeError 什么的).它不区分您是使用 if 作为属性名、变量名、函数名还是类型名.它永远不可能是标识符,因为解析器总是为其分配关键字"标签,并使其成为与标识符不同的标记.

So the code doesn't even get to the point where there's attribute access, it's simply rejected by the parser, just like incorrect indentation (which is why it's a SyntaxError, and not AttributeError or something). It doesn't differentiate whether you use if as an attribute name, a variable name, a function name, or a type name. It can never be an identifier, simply because parser always assigns it "keyword" label and makes it a different token than identifiers.

在大多数语言中都是一样的,语言语法(+ 词法分析器规范)就是它的文档.语言规范明确提及.它在 Python 3 中也没有改变.

It's the same in most languages, and language grammar (+ lexer specification) is the documentation for that. Language spec mentions it explicitly. It also doesn't change in Python 3.

此外,仅仅因为您可以使用 setattr__dict__ 来制作具有保留名称的属性,并不意味着您应该.不要强迫自己/API 用户使用 getattr 代替自然属性访问.getattr 应该在需要访问变量属性名称时保留.

Also, just because you can use setattr or __dict__ to make an attribute with a reserved name, doesn't mean you should. Don't force yourself/API user to use getattr instead of natural attribute access. getattr should be reserved for when access to a variable attribute name is needed.

相关文章