Встроенные константы в Python недоступны через __builtins__ с использованием точечного синтаксиса?

Читая Встроенные константы, можно увидеть, что, например, False — это встроенная константа.

Получить его можно с помощью:

>>> print(getattr(__builtins__, "False"))
False

Но это не удается:

>>> print(__builtins__.False)
File "<stdin>", line 1
    print(__builtins__.False)
                       ^^^^^
SyntaxError: invalid syntax

Я предполагаю, что это не удается, потому что слово False распознается интерпретатором как ключевое слово/константа, на которое оно ссылается, и поэтому поиск атрибута не происходит? В документации говорится о getattr:

Возвращает значение именованного атрибута объекта. имя должно быть строкой. Если строка является именем одного из атрибутов объекта, результатом будет значение этого атрибута. Например, getattr(x, 'foobar') эквивалентно x.foobar.

Но для зарезервированного ключевого слова (?) это не так?

Я думаю, что __builtins__ предназначен только для встроенных функций, а не для переменных.

Barmar 12.07.2024 23:36

«и поэтому поиск атрибутов не выполняется». Вы даже не дошли до поиска атрибутов. False маркируется как ключевое слово до того, как парсер его проверит, поэтому __builtins__.False — это просто недопустимый синтаксис.

Tordek 12.07.2024 23:55
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
57
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В выражениях атрибутов , some_obj.some_attrsome_attr должно быть допустимым именем Python (идентификатором), а False не является таковым именно потому, что это ключевое слово. Отсюда и синтаксическая ошибка (код даже не компилируется).

>>> import keyword
>>> keyword.iskeyword("False")
True

Сравните разницу между:

>>> import dis
>>> dis.dis("sum")
  0           0 RESUME                   0

  1           2 LOAD_NAME                0 (sum)
              4 RETURN_VALUE
>>> dis.dis("False")
  0           0 RESUME                   0

  1           2 RETURN_CONST             0 (False)
>>> dis.dis("1337")
  0           0 RESUME                   0

  1           2 RETURN_CONST             0 (1337)

@nocomment они являются действительными идентификаторами только в том смысле, что они были бы действительными идентификаторами, если бы не тот факт, что они являются зарезервированными словами.

juanpa.arrivillaga 13.07.2024 00:05

@nocomment еще раз: они не являются допустимыми идентификаторами именно потому, что являются ключевыми словами. Вот почему он поднимает SyntaxError

juanpa.arrivillaga 13.07.2024 00:10

Я имею в виду «недействителен», как в «не может использоваться в качестве обычных идентификаторов», что является определением ключевого слова, а не как в «иначе не будет действительным идентификатором».

juanpa.arrivillaga 13.07.2024 00:13
Ответ принят как подходящий

Я предполагаю, что это не удается, потому что слово False распознается интерпретатором как ключевое слово [...] и поэтому поиск атрибутов не выполняется.

Да, это правильно. Вот почему вы получаете SyntaxError вместо ошибки выполнения, например AttributeError.

Другие встроенные константы вполне доступны, например:

>>> __builtins__.NotImplemented
NotImplemented

Подробнее о ключевых словах

См. документацию по ключевым словам :

Следующие идентификаторы используются как зарезервированные слова или ключевые слова языка и не могут использоваться как обычные идентификаторы. Их нужно писать именно так, как написано здесь:

False None True [...]

Сравните это с последним предложением документа getattr():

name не обязательно должен быть идентификатором Python (см. setattr()).

И в setattr():

Атрибут, имя которого не является идентификатором, не будет доступен с использованием точечной записи, но доступен через getattr() и т. д.

Это означает, что вы также можете устанавливать/получать атрибуты, которые даже отдаленно не являются синтаксически допустимыми для Python, например:

>>> class Foo: pass
... 
>>> f = Foo()
>>> setattr(f, '$', 'bar')
>>> getattr(f, '$')
'bar'
>>> f.$
  File "<stdin>", line 1
    f.$
      ^
SyntaxError: invalid syntax

Спасибо, идеальное объяснение. Ответ принят!

jensa 13.07.2024 22:37

Другие вопросы по теме