Por lo que he leído, hay dos formas de depurar código en Python:
Con un depurador tradicional como
pdb
oipdb
. Esto apoya comandos comoc
paracontinue
,n
parastep-over
,s
parastep-into
, etc.), pero que no tienen acceso directo a una cáscara IPython que puede ser extremadamente útil para la inspección de objetos.Usando IPython mediante la incorporación de una cáscara IPython en el código. Puede hacerlo
from ipython import embed
y luego usarloembed()
en su código. Cuando su programa / script llega a unaembed()
declaración, se lo deja caer en un shell IPython. Esto permite la inspección completa de los objetos y la prueba del código de Python utilizando todas las ventajas de IPython. Sin embargo, al usarloembed()
no puedes paso a paso a por el código con los atajos de teclado útiles.
¿Hay alguna forma de combinar lo mejor de ambos mundos? Es decir
- Ser capaz de paso a paso a través de su código con práctico AP / atajos de teclado IPDB.
- En cualquiera de estos pasos (por ejemplo, en una declaración dada), tenga acceso a un shell de IPython completo .
Depuración de IPython como en MATLAB:
Se puede encontrar un ejemplo de este tipo de "depuración mejorada" en MATLAB, donde el usuario siempre tiene acceso completo al motor / shell de MATLAB, y aún puede hacerlo paso a paso través de su código, definir puntos de interrupción condicionales, etc. Lo que he discutido con otros usuarios, esta es la función de depuración que la gente más echa de menos al pasar de MATLAB a IPython.
Depuración de IPython en Emacs y otros editores:
No quiero hacer la pregunta demasiado específica, pero trabajo principalmente en Emacs, así que me pregunto si hay alguna forma de incorporar esta funcionalidad. Idealmente , Emacs (o el editor) permitiría al programador establecer puntos de interrupción en cualquier parte del código y comunicarse con el intérprete o depurador para que se detenga en la ubicación de su elección y llevar a un intérprete completo de IPython en esa ubicación.
!
comando que ejecuta cualquier comando de python en el punto de interrupciónRespuestas:
Puedes usar la
%pdb
magia de IPython . Simplemente llame%pdb
a IPython y cuando se produzca un error, se lo colocará automáticamenteipdb
. Si bien no tienes el paso de inmediato, estás enipdb
después.Esto facilita la depuración de funciones individuales, ya que puede cargar un archivo
%load
y luego ejecutar una función. Podría forzar un error con unassert
en la posición correcta.%pdb
Es una línea mágica. Llamar como%pdb on
,%pdb 1
,%pdb off
o%pdb 0
. Si se llama sin argumento, funciona como una palanca.fuente
ipython --pdb file.py -- args
y se deja caer a ipdb ante una excepción. Podría valer la pena agregar a la respuesta.¿Qué pasa con ipdb.set_trace ()? En su código:
import ipdb; ipdb.set_trace()
Actualización : ahora en Python 3.7, podemos escribir
breakpoint()
. Funciona igual, pero también obedece a laPYTHONBREAKPOINT
variable de entorno. Esta característica proviene de este PEP .Esto permite una inspección completa de su código, y tiene acceso a comandos como
c
(continuar),n
(ejecutar la siguiente línea),s
(ingresar al método en el punto) y así sucesivamente.Consulte el repositorio de ipdb y una lista de comandos . IPython ahora se llama (editar: parte de) Jupyter .
ps: tenga en cuenta que un comando ipdb tiene prioridad sobre el código python. Entonces, para escribir
list(foo)
, necesitaríasprint list(foo)
.Además, si le gusta la solicitud de ipython (sus modos emacs y vim, historial, finalizaciones, ...) es fácil obtener lo mismo para su proyecto, ya que se basa en el kit de herramientas de solicitud de Python .
fuente
ipdb
en Emacs usandoRealGUD
yisend-mode
hacer exactamente lo que pide el OP.breakpoint()
es maravilloso. En PyCharm incluso te deja caer en el depurador de PyCharm. También es una forma rápida de ingresar al depurador PyCharm desde las funciones que se pegaron en la consola.(Actualización el 28 de mayo de 2016) Uso de RealGUD en Emacs
Para cualquier persona en Emacs, este hilo muestra cómo lograr todo lo descrito en el OP (y más) usando
ipdb
).isend-mode
.La combinación de estos dos paquetes es extremadamente poderosa y permite recrear exactamente el comportamiento descrito en el OP y hacer aún más.
Más información sobre el artículo wiki de RealGUD para ipdb.
Respuesta original:
Después de haber probado muchos métodos diferentes para depurar Python, incluido todo lo mencionado en este hilo, una de mis formas preferidas de depurar Python con IPython es con shells incrustados.
Definición de un shell IPython incrustado personalizado:
Agregue lo siguiente en un script a su
PYTHONPATH
, para que el métodoipsh()
esté disponible.Luego, cada vez que quiero depurar algo en mi código, lo coloco
ipsh()
justo en el lugar donde necesito hacer una inspección de objetos, etc. Por ejemplo, digamos que quiero depurarmy_function
continuaciónUtilizándolo:
y luego invoco
my_function(2)
de una de las siguientes maneras:Independientemente de cómo lo invoque, el intérprete se detiene en la línea que dice
ipsh()
. Una vez que haya terminado, puede hacerloCtrl-D
y Python reanudará la ejecución (con cualquier actualización variable que haya realizado). Tenga en cuenta que, si ejecuta el código desde un IPython normal, el shell de IPython (caso 2 anterior), el nuevo shell de IPython estará anidado dentro del que lo invocó, lo cual está perfectamente bien, pero es bueno tenerlo en cuenta. De todos modos, una vez que el intérprete se detiene en la ubicación deipsh
, puedo inspeccionar el valor dea
(que puede ser2
), ver qué funciones y objetos están definidos, etc.El problema:
La solución anterior se puede usar para que Python se detenga en cualquier lugar que desee en su código y luego lo deje en un intérprete de IPython completo. Desafortunadamente, no le permite agregar o eliminar puntos de interrupción una vez que invoca el script, lo cual es muy frustrante. En mi opinión, este es el único que impide que IPython se convierta en una gran herramienta de depuración para Python.
Lo mejor que puedes hacer por ahora:
Una solución alternativa es colocar
ipsh()
a priori en las diferentes ubicaciones donde desea que el intérprete de Python inicie un shell de IPython (es decir, abreakpoint
). Luego puede "saltar" entre diferentes "puntos de interrupción" predefinidos y codificadosCtrl-D
, lo que saldría del shell IPython incrustado actual y se detendría nuevamente cada vez que el intérprete llegue a la siguiente llamada paraipsh()
.Si sigue esta ruta, una forma de salir del "modo de depuración" e ignorar todos los puntos de interrupción subsiguientes es utilizar lo
ipshell.dummy_mode = True
que hará que Python ignore cualquier instanciación posterior delipshell
objeto que creamos anteriormente.fuente
import inspect
antes de que funcionara. Sin embargo, la personalización de la línea de comandos parece estar rota para mí.import ipdb; ipdb.set_trace()
? Tal vez extraño algo, pero no veo la ventaja de su método mucho más complicado.Puede iniciar la sesión de IPython desde pudb y volver a la sesión de depuración como desee.
Por cierto, ipdb está usando IPython detrás de escena y en realidad puedes usar la funcionalidad de IPython como la finalización de TAB y los comandos mágicos (el que comienza con
%
). Si está de acuerdo con ipdb, puede iniciarlo desde IPython usando comandos como%run
y%debug
. la sesión de ipdb es realmente mejor que la simple IPython en el sentido de que puede subir y bajar en el seguimiento de la pila, etc. ¿Qué falta en ipdb para "inspección de objetos"?Además, python.el incluido con Emacs> = 24.3 tiene un buen soporte para ipdb.
fuente
M-x ansi-term
búfer separado y luego uso el modo isend para vincular mis búferes de origen al búfer de IPython para poder enviar código al intérprete de IPython con un atajo de teclado que envía automáticamente la%paste
magia al búfer de IPython. Esto me permite probar rápidamente regiones en IPython. Siempre ejecuto mis programas desde este shell de IPython conrun
y usoembed()
para detener.ipdb
sesión de depuración usandopython.el
y tener cosas comosend-region
etc. en el shell correspondiente? En general, ¿dónde puedo encontrar más información sobre esto?%run
o%debug
. Supongo queimport ipdb; ipdb.set_trace()
también funciona. No creo que pueda enviar varias líneas a ipdb. Esa es la limitación de ipdb. Pero probablemente el%paste
truco funcione. Es posible que desee enviar una solicitud de función al desarrollador de IPython.Parece que el enfoque en la respuesta de @ gaborous está en desuso .
El nuevo enfoque parece ser:
fuente
ipdb
declaraciones dentro de ipython shell, mientras se depura?Prefijar un "!" El símbolo de los comandos que escribe en pdb parece tener el mismo efecto que hacer algo en un shell de IPython. Esto funciona para acceder a la ayuda para una determinada función, o incluso nombres de variables. Quizás esto te ayude hasta cierto punto. Por ejemplo,
Pero! Help (numpy.transpose) le dará la página de ayuda esperada en numpy.transpose. De manera similar para los nombres de variables, supongamos que tiene una variable l, al escribir "l" en pdb se enumera el código, pero! L imprime el valor de l.
fuente
¿Intentaste este consejo ?
fuente
Puedes comenzar
IPython
desde dentroipdb
!Induzca al
ipdb
depurador 1 :Ingrese IPython desde dentro en la
ipdb>
consola 2 :Regrese a la
ipdb>
consola desde adentroIPython
:Si tienes la suerte de estar usando Emacs, ¡las cosas pueden hacerse aún más cómodas!
Esto requiere usar
M-x shell
. Usandoyasnippet
y bm , defina el siguiente fragmento. Esto reemplazará el textoipdb
en el editor con laset-trace
línea. Después de insertar el fragmento, la línea se resaltará para que sea fácilmente perceptible y navegable. UseM-x bm-next
para navegar.1 Todo en una línea para borrar fácilmente. Como
imports
solo ocurre una vez, este formulario garantizaipdb
que se importará cuando lo necesite sin gastos adicionales.2 Puede ahorrarse algo de texto importando
IPython
dentro de su.pdbrc
archivo :Esto le permite simplemente llamar
embed()
desde dentroipdb
(por supuesto, solo cuando IPython está instalado).fuente
Una opción es utilizar un IDE como Spyder que debería permitirle interactuar con su código mientras se depura (de hecho, utilizando una consola IPython). De hecho, Spyder es muy parecido a MATLAB, lo que supongo que fue intencional. Eso incluye inspectores variables, edición variable, acceso incorporado a la documentación, etc.
fuente
la respuesta correcta, fácil, genial y exacta para la pregunta es usar% run macro con la marca -d.
fuente
%save /tmp/foo.py x-y
El código que quiero ejecutar y depurar y luego%run -d /tmp/foo.py
establecer el punto de interrupción donde quiera. ¡Gran respuesta!Si escribe exit () en la consola embed (), el código continuará y pasará a la siguiente línea embed ().
fuente
El pyzo IDE tiene capacidades similares como el PO pidió. No tiene que comenzar en modo de depuración. De manera similar a MATLAB, los comandos se ejecutan en el shell. Cuando configura un punto de interrupción en alguna línea de código fuente, el IDE detiene la ejecución allí y también puede depurar y emitir comandos regulares de IPython.
Sin embargo, parece que entrar no funciona bien (¿todavía?) (Es decir, detenerse en una línea y luego pasar a otra función) a menos que configure otro punto de interrupción.
Aún así, viniendo de MATLAB, esta parece ser la mejor solución que he encontrado.
fuente
Desde python 3.2, tiene el
interact
comando, que le da acceso al espacio completo de comandos de python / ipython.fuente
Ejecutar desde dentro de IPython-shell de Emacs y el conjunto de puntos de interrupción a través de pdb.set_trace () debería funcionar.
Comprobado con python-mode.el, Mx ipython RET, etc.
fuente
Desarrollando nuevo código
Depuración dentro de IPython
Ejemplo de celda:
Depuración de código existente
IPython dentro de la depuración
pytest ... --pdbcls=IPython.terminal.debugger:TerminalPdb --pdb
breakpoint()
,python -m ipdb
, etc.Pensamientos sobre Python
Estoy de acuerdo con el OP en que muchas cosas que MATLAB hace muy bien que Python aún no tiene y realmente debería, ya que casi todo en el lenguaje favorece la velocidad de desarrollo sobre la velocidad de producción. Quizás algún día contribuya más que triviales correcciones de errores a CPython.
https://github.com/ipython/ipython/commit/f042f3fea7560afcb518a1940daa46a72fbcfa68
Consulte también ¿Es posible ejecutar comandos en IPython con depuración?
fuente