En python, ¿por qué 0xbin () devuelve False? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Al introducir el comando 0xbin() devuelve False:

>>> 0xbin()
False

¿Por qué sucede eso? Esta sintaxis no debería tener ningún significado. Las funciones no pueden comenzar con 0, no hay" i "y" n " en hexadecimal, y la función bin debe tener algunos argumento.

 192
Author: Aran-Fey, 2018-07-25

4 answers

Python parece interpretar 0xbin() como 0xb in (), lo que significa once en una tupla vacía. La respuesta es no, por lo tanto False.

 232
Author: YSelf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-25 14:18:15

Si desensamblas el código, verás que la respuesta de Yself , que menciona que 0xbin() se interpreta como 0xb in (), se confirma:

>>> import dis
>>> dis.dis('0xbin()')
  1           0 LOAD_CONST               0 (11)
              2 BUILD_TUPLE              0
              4 COMPARE_OP               6 (in)
              6 RETURN_VALUE
 138
Author: Chris_Rands,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-27 17:58:07

Puede utilizar el propio tokenizador de Python para comprobar!

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

Esto imprime los tokens en su cadena, separados por espacios. En este caso, el resultado será:

0xb in ( ) 

En otras palabras, devuelve False porque el número 11 (0xb) no está en la tupla vacía (()).

(Gracias a Roman Odaisky por sugerir el uso de tokenize en los comentarios!)

EDITAR: Para explicar el código un poco más a fondo: la función tokenize espera la entrada en un formato un poco extraño, por lo que io.BytesIO(line).readline es una función que convierte una secuencia de bytes en algo que tokenize puede leer. tokenize luego lo tokeniza y devuelve una serie de namedtuple s; tomamos la cadena que representa a cada uno y los unimos con espacios. La parte type != 59 se usa para ignorar el especificador de codificación que de otro modo se mostraría al principio.

 60
Author: Draconis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-26 18:08:15

Puede usar el módulo AST para obtener el árbol de sintaxis abstracta de la expresión:

>>> 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())
                                         ]
                            ))])'

Vea la gramática abstracta para saber cómo interpretar la expresión, pero tl;dr: Num(n=11) es la parte 0xb, y Tuple(elts=[], ...) apunta hacia una tupla vacía en lugar de una llamada a una función.

 53
Author: Pål GD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-26 11:21:51