visual studio online hacer debugger debug como code python debugging python-3.x list-comprehension

studio - pdb python



Enumere el error del alcance de la comprensiĆ³n del depurador de Python (2)

En Python 3, debe utilizar el comando interact en pdb antes de poder acceder a cualquier variable no global debido a un cambio en la forma en que se implementan las comprensiones.

>>> def foo(): [][0] ... >>> foo() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 1, in foo IndexError: list index out of range >>> import pdb;pdb.pm() > <stdin>(1)foo() (Pdb) x = 4 (Pdb) [x for _ in range(2)] *** NameError: name ''x'' is not defined (Pdb) interact *interactive* >>> [x for _ in range(2)] [4, 4] >>>

Al depurar mi código, quiero usar una lista de comprensión. Sin embargo, parece que no puedo evaluar una lista de comprensión del depurador cuando estoy dentro de una función.

Estoy usando Python 3.4.

Contenidos del guión :

$ cat test.py #!/usr/bin/python def foo(): x = [1, 2, 3, 3, 4] print(x) foo()

Depuración interactiva:

$ python3 -mpdb test.py > /tmp/test.py(3)<module>() -> def foo(): (Pdb) step > /tmp/test.py(8)<module>() -> foo() (Pdb) --Call-- > /tmp/test.py(3)foo() -> def foo(): (Pdb) > /tmp/test.py(4)foo() -> x = [1, 2, 3, 3, 4] (Pdb) > /tmp/test.py(6)foo() -> print(x) (Pdb) p [x for _ in range(1)] *** NameError: name ''x'' is not defined (Pdb) p x [1, 2, 3, 3, 4]

¿Por qué x es desconocido para la lista de comprensión? ¿Cómo podría evaluar una lista de comprensión del depurador o lograr un comportamiento equivalente? ¿Es esto un error, o es una limitación fundamental para el depurador?


pdb parece estar ejecutando el código con:

eval(compiled_code, globals(), locals())

(o tal vez solo eval(string, globals(), locals()) ).

Desafortunadamente, en la compilación Python no conoce las variables locales. Esto no importa normalmente:

import dis

dis.dis(compile("x", "", "eval")) #>>> 1 0 LOAD_NAME 0 (x) #>>> 3 RETURN_VALUE

pero cuando se introduce otro ámbito, como con una lista de comprensión de lambda , esto se compila mal:

dis.dis(compile("(lambda: x)()", "", "eval")) #>>> 1 0 LOAD_CONST 0 (<code object <lambda> at 0x7fac20708d20, file "", line 1>) #>>> 3 LOAD_CONST 1 (''<lambda>'') #>>> 6 MAKE_FUNCTION 0 #>>> 9 CALL_FUNCTION 0 (0 positional, 0 keyword pair) #>>> 12 RETURN_VALUE

# The code of the internal lambda dis.dis(compile("(lambda: x)()", "", "eval").co_consts[0]) #>>> 1 0 LOAD_GLOBAL 0 (x) #>>> 3 RETURN_VALUE

Tenga en cuenta que es un LOAD_GLOBAL donde x está en el ámbito local.

Aquí hay un truco totalmente estúpido para evitarlo:

(Pdb) eval("(lambda: x)()", vars()) [1, 2, 3, 3, 4]