为什么在python中可以将类属性命名为保留字?

时间:2017-10-25 06:43:44

标签: python reserved-words class-attributes

似乎保留字不能用作python中的属性:

$ python
Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:51:32) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
>>>     global = 3
  File "<stdin>", line 2
    global = 3
           ^
SyntaxError: invalid syntax

这似乎是明智的,因为它含糊不清:我在这里使用global关键字吗?很难说。

但这不是明智的事情:

>>> class A: pass
>>> a = A()
>>> a.global = 3
  File "<stdin>", line 1
    a.global = 3
           ^
SyntaxError: invalid syntax
>>> a.def = 4
  File "<stdin>", line 1
    a.def = 4
        ^
SyntaxError: invalid syntax
>>> a.super = 5
>>> a.abs = 3
>>> a.set = 5
>>> a.False = 5
  File "<stdin>", line 1
    a.False = 5
          ^
SyntaxError: invalid syntax
>>> a.break = 5
  File "<stdin>", line 1
    a.break = 5
          ^
SyntaxError: invalid syntax

为什么会出现这种限制?我没有孤立地使用保留字,而是作为类属性:根本没有歧义。为什么python会关心这个?

2 个答案:

答案 0 :(得分:4)

它无处可怜。

当然,你可以允许它。破解令牌化程序和解析器,以便令牌化程序知道解析上下文并在解析器期望属性访问时发出NAME令牌而不是关键字令牌,或者让它在DOT之后始终发出NAME令牌而不是关键字。但那能得到什么呢?

您使解析器和标记器更复杂,因此更容易出错。对于人类读者来说,你更难以阅读。您限制了未来的语法可能性。

时,你会引起混淆
Foo.for = 3

解析和

class Foo:
    for = 3

抛出一个SyntaxError。你使Python不那么一致,更难学,也更难理解。

尽管如此,你还是获得了写x.for = 3的能力。我能说的最好的一点就是,在添加x.fibble = 3关键字后,它会阻止fibble之类的内容破坏,但即使这样,fibble的所有其他用途仍然存在打破。不值得。如果您想使用疯狂的属性名称,则可以使用setattrgetattr

Python尽力使语法变得简单。它的解析器是LL(1),LL(1)解析器的限制被认为是有益的specifically because they prevent going overboard with crazy grammar rules

  

简单比复杂更好。这个想法延伸到解析器。将Python的语法限制为LL(1)解析器是一种祝福,而不是诅咒。它让我们戴上手铐,阻止我们过度使用,最终得到时髦的语法规则,就像其他一些未命名的动态语言,如Perl。

x.for = 3这样的东西不符合这种设计理念。

答案 1 :(得分:0)

要了解此限制背后的原因,您需要了解计算机语言的工作原理。

最初,您有一个文本文件。您将此文本提供给字符串标记器(称为词法分析器),它识别词汇元素,如单词,运算符,注释,数字,字符串等。基本上,词法分析器除了字符之外什么都不知道。它将文本文件转换为类型化标记流。

然后将这个令牌流送入解析器。解析器处理更高级别的构造,例如方法定义,类定义,导入语句等。例如,解析器知道函数定义以&#34; def&#34;开头,后跟一些名称(类型标识符的标记) ,然后是冒号,还有一堆缩进的线条。这意味着一些单词,如&#34; def&#34;,&#34; return&#34;,&#34; if&#34;保留给解析器,因为它们是语言语法的一部分。

解析的结果是一个名为抽象语法树(AST)的数据结构。 AST直接对应于文本文件的内容和结构。在AST中,没有关键字,因为它们已经达到了目的。另一方面,保留标识符(变量和函数的名称等),因为稍后编译器/解释器需要它们。

简而言之,关键字的存在是为了给文本提供结构。没有结构,程序就不可能确定性地分析文本。如果您尝试将关键字用于其他内容,则会破坏结构。分析结构后,不再需要它们。本质上,这意味着语言的作者必须绘制一条线并为结构保留一些单词,同时让所有其他单词免费供程序员使用。

这不仅仅是特定于Pyhthon的。每种语言都是一样的。如果您没有文本文件,则不需要关键字。从技术上讲,语言有可能克服这种限制,但它会使事情复杂化而没有任何实际好处。将解析器与其他语言分开是非常有意义的,你不会以其他任何方式想要它。