In python, why does 0xbin() return False? [duplicate]
Solution 1:
Python seems to interpret 0xbin()
as 0xb in ()
, meaning is eleven in an empty tuple.
The answer is no, therefore False
.
Solution 2:
If you disassemble the code, you'll see that Yself's answer, which mentions that 0xbin()
is interpreted as 0xb in ()
, is confirmed:
>>> import dis
>>> dis.dis('0xbin()')
1 0 LOAD_CONST 0 (11)
2 BUILD_TUPLE 0
4 COMPARE_OP 6 (in)
6 RETURN_VALUE
Solution 3:
You can use Python's own tokenizer to check!
import tokenize
import io
line = b'0xbin()'
print(' '.join(token.string for token in tokenize.tokenize(io.BytesIO(line).readline) if token.type!=59))
This prints the tokens in your string, separated by spaces. In this case, the result will be:
0xb in ( )
In other words, it returns False because the number 11 (0xb
) is not in the empty tuple (()
).
(Thanks to Roman Odaisky for suggesting the use of tokenize
in the comments!)
EDIT: To explain the code a bit more thoroughly: the tokenize
function expects input in a bit of a weird format, so io.BytesIO(line).readline
is a function that turns a sequence of bytes into something tokenize
can read. tokenize
then tokenizes it and returns a series of namedtuple
s; we take the string representing each one and join them together with spaces. The type != 59
part is used to ignore the encoding specifier that would otherwise show up at the beginning.
Solution 4:
You can use the AST module to get the abstract syntax tree of the expression:
>>> 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())
]
))])'
See the abstract grammar for how to interpret the expression, but tl;dr: Num(n=11)
is the 0xb
part, and Tuple(elts=[], ...)
hints towards an empty tuple rather than a function call.