В python, почему 0xbin() возвращает False?

Ввод команды 0xbin() возвращает False:

>>> 0xbin()
False

Почему это происходит? Этот синтаксис не должен иметь никакого значения. Функции не могут начинаться с 0, в шестнадцатеричном виде нет "i" и "n", а функция bin должна иметь некоторые аргументы.

Ответы

Ответ 1

Кажется, что Python интерпретирует 0xbin() как 0xb in(), что означает одиннадцать в пустом кортеже. Ответ - нет, поэтому False.

Ответ 2

Если вы разобраете код, вы увидите ответ Yself, в котором говорится, что 0xbin() интерпретируется как 0xb in(), подтверждается:

>>> import dis
>>> dis.dis('0xbin()')
  1           0 LOAD_CONST               0 (11)
              2 BUILD_TUPLE              0
              4 COMPARE_OP               6 (in)
              6 RETURN_VALUE

Ответ 3

Вы можете использовать собственный токенизатор Python для проверки!

import tokenize
import io
line = b'0xbin()'
print(' '.join(token.string for token in tokenize.tokenize(io.BytesIO(line).readline) if token.type!=59))

Это печатает маркеры в вашей строке, разделенные пробелами. В этом случае результатом будет:

0xb in ( ) 

Другими словами, он возвращает False, потому что число 11 (0xb) не находится в пустом кортеже (()).

(Спасибо Роману Одайскому за предложение использовать tokenize в комментариях!)

EDIT: для более подробного объяснения кода: функция tokenize ожидает ввода в немного странном формате, поэтому io.BytesIO(line).readline - это функция, которая превращает последовательность байтов в то, что может быть прочитано в tokenize. tokenize затем токенизирует его и возвращает серию namedtuple s; мы берем строку, представляющую каждый, и объединяем их вместе с пробелами. Часть type != 59 используется для игнорирования спецификатора кодирования, который в противном случае отображался бы в начале.

Ответ 4

Вы можете использовать модуль AST для получения абстрактного синтаксического дерева выражения:

>>> import ast
>>> m = ast.parse('0xbin()')
>>> ast.dump(m)
'Module(
    body=[Expr(
               value=Compare(left=Num(n=11),
                             ops=[In()],
                             comparators=[Tuple(elts=[],
                                                ctx=Load())
                                         ]
                            ))])'

См. Абстрактную грамматику для интерпретации выражения, но tl; dr: Num(n=11) - это часть 0xb, а Tuple(elts=[],...) указывает на пустой кортеж, а не на вызов функции.