Ciò interromperà il processo (a meno che non si avvia in un thread), ma è possibile utilizzare il code
modulo per avviare una console Python:
import code
code.interact()
Questo bloccherà fino a quando l'utente esce dalla console interattiva eseguendo exit()
.
Il modulo code
è disponibile almeno in Python v2.6, probabilmente altri.
Tendo ad usare questo approccio in combinazione con i segnali per il mio lavoro su Linux (per Windows, vedi sotto). I schiaffo questo nella parte superiore del mio script Python:
import code
import signal
signal.signal(signal.SIGUSR2, lambda sig, frame: code.interact())
E poi innescare da una shell con kill -SIGUSR2 <PID>
, dove <PID>
è l'ID del processo. Il processo si arresta quindi tutto ciò che sta facendo e presenta una console:
Python 2.6.2 (r262:71600, Oct 9 2009, 17:53:52)
[GCC 3.4.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
Generalmente da lì sarò caricare il componente lato server di un debugger remoto come l'eccellente WinPDB.
Windows non è un sistema operativo conforme allo POSIX e pertanto non fornisce gli stessi segnali di Linux. Tuttavia, Python v2.2 and above expose a Windows-specific signal SIGBREAK
(attivato premendo CTRL
+ Pause/Break
). Questo non interferisce con l'operazione normale CTRL
+ C
(SIGINT
) e quindi è un'alternativa pratica.
Pertanto un portatile, ma un po 'brutto, la versione di quanto sopra è:
import code
import signal
signal.signal(
vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR2"),
lambda sig, frame: code.interact()
)
I vantaggi di questo approccio:
- Nessun moduli esterni (tutta roba standard di Python)
- consuma a malapena qualsiasi risorsa fino a quando non viene attivata (2x importazione)
Ecco il codice che uso nel mio ambiente di produzione che caricherà il lato server di WinPDB (se disponibile) e ricadrà all'apertura di una console Python.
# Break into a Python console upon SIGUSR1 (Linux) or SIGBREAK (Windows:
# CTRL+Pause/Break). To be included in all production code, just in case.
def debug_signal_handler(signal, frame):
del signal
del frame
try:
import rpdb2
print
print
print "Starting embedded RPDB2 debugger. Password is 'foobar'"
print
print
rpdb2.start_embedded_debugger("foobar", True, True)
rpdb2.setbreak(depth=1)
return
except StandardError:
pass
try:
import code
code.interact()
except StandardError as ex:
print "%r, returning to normal program flow" % ex
import signal
try:
signal.signal(
vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR1"),
debug_signal_handler
)
except ValueError:
# Typically: ValueError: signal only works in main thread
pass
quindi, in sostanza, un debugger? – st0le
qualcosa come l'interprete della riga di comando python.exe –
versione pdb: https://stackoverflow.com/questions/25308847/attaching-a-processo-con-pdb –