为什么不能属性的名称是Python的关键字?为什么不能属性的名称是Python的关键字?(Why c

2019-05-12 11:50发布

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

>>> 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. IS /这里是在属性名以上限制记录?

它将使意义做o.class = … ,在我的节目之一,我有点失望,不能够做到这一点( o.class_会的工作,但它看起来并不那么简单)。

PS:这个问题显然是ifclass是Python的关键字。 问题是,为什么使用关键字作为属性名称将被禁止(我看不出有任何含糊的表达o.class = 123 ),以及这是否证明

Answer 1:

因为解析器是简单的关键字时,总是关键词,而不是上下文(例如if是一个关键字的语句级的时候,只是一个标识符时,在表达式中-对if它会是因为双硬X if C else Y ,而for在列表内涵和发电机表达式)使用。

因此,代码甚至没有去那里的属性接入点,它只是由解析器拒绝,就像不正确的缩进(这就是为什么它是一个SyntaxError ,而不是AttributeError或东西)。 它不区分是否使用if作为属性名,变量名,函数名,或一个类型名称。 它不可能是一个标识符,只是因为解析器总是赋予它“关键字”标签,并使其成为一个不同的令牌比标识符。

这是大多数语言相同,语言的语法(词法+规范)是该文档。 语言规范提到它明确 。 它也不会在Python 3改变。

此外,仅仅是因为你可以使用setattr__dict__ ,以与保留名称的属性,并不意味着你应该 。 不要强迫自己/ API用户使用getattr而不是自然属性的访问。 getattr应保留需要访问一个变量属性名时。



Answer 2:

因为if是一个关键词。 你有类似的问题o.whileo.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];

可以(有一点困难)基于地方出现这些词汇元素(什么存在于其中的任何一方)一个复杂的分析器进行评估。 但是,(至少部分地)的简单(和可读性)的利益,这是没有这样做。



文章来源: Why can't attribute names be Python keywords?