Почему имена атрибутов не могут быть ключевыми словами Python? - PullRequest
10 голосов
/ 17 марта 2012

Существует ограничение на синтаксис доступа к атрибутам в Python (по крайней мере, в реализации CPython 2.7.2):

>>> 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_ сработает, но выглядит не так просто).

PS : Очевидно, проблема в том, что if и class являются ключевыми словами Python. Вопрос , почему использование ключевых слов в качестве имен атрибутов было бы запрещено (я не вижу никакой двусмысленности в выражении o.class = 123), и является ли это документированным .

Ответы [ 2 ]

8 голосов
/ 17 марта 2012

Поскольку синтаксический анализатор проще, когда ключевые слова всегда являются ключевыми словами, а не контекстными (например, if - это ключевое слово на уровне оператора, а просто идентификатор внутри выражения - для if это будет вдвое сложнее, потому что X if C else Y, а for используется в списках и выражениях генератора).

Таким образом, код даже не доходит до точки доступа к атрибутам, он просто отклоняется синтаксическим анализатором, точно так же, как неверный отступ (именно поэтому это SyntaxError, а не AttributeError или что-то в этом роде). Он не определяет, используете ли вы if в качестве имени атрибута, имени переменной, имени функции или имени типа. Он никогда не может быть идентификатором, просто потому, что синтаксический анализатор всегда назначает ему метку «ключевого слова» и делает его отличным от токена идентификатором.

Это то же самое в большинстве языков, и грамматика языка (спецификация + lexer) является документацией для этого. В спецификации языка это явно указано . Это также не меняется в Python 3.

Кроме того, то, что вы можете использовать setattr или __dict__ для создания атрибута с зарезервированным именем, не означает, что вы должны . Не заставляйте себя / пользователя API использовать getattr вместо естественного доступа к атрибутам. getattr должно быть зарезервировано для случаев, когда необходим доступ к имени атрибута переменной.

1 голос
/ 17 марта 2012

Потому что 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];

можно (с небольшими трудностями) оценить с помощью сложного синтаксического анализатора, основанного на том, где находятся эти лексические элементы (и что существует по обе стороны от них). Но (хотя бы частично) в интересах простоты (и читабельности) это не сделано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...