Me gustaría tener acceso en tiempo real tanto a la entrada del intérprete como a los errores y a la salida estándar. Preferiblemente esta información se escribiría en un archivo, de modo que pueda sondear el archivo para ver los cambios después de que se haya ingresado cada comando de intérprete. Por ejemplo, dada una sesión intérprete:¿Cómo registrar todo lo que ocurre en una sesión de shell interactiva de Python?
>>> 5 * 7
35
>>> print("Hello, world!")
Hello, world!
>>> "Hello, world!"
'Hello, world!'
me gustaría ver lo siguiente en un archivo de registro:
> 5 * 7
35
> print("Hello, world!")
Hello, world!
> "Hello, world!"
'Hello, world!'
El formato no es importante; lo importante es que puedo buscar palabras clave en el archivo para desencadenar eventos interactivos durante la sesión.
Lo que he aprendido hasta ahora tratando de lograr esto:
módulo de Python code
me permite crear un objeto InteractiveConsole
, el método raw_input
de los cuales puedo redefinir para iniciar la sesión en un archivo, así:
import code
class LoggedConsole(code.InteractiveConsole):
def __init__(self, locals):
super(LoggedConsole, self).__init__(locals)
self.file = open('consolelog.dat', 'a')
def __del__(self):
self.file.close()
def raw_input(self, prompt=""):
data = input(prompt)
self.file.write(data+'\n')
return data
Además, InteractiveConsole
utiliza un incorporada write
método para registrar los errores, que puedo redefinir a:
def write(self, data):
sys.stderr.write(data)
self.file.write(data+'\n')
También he aprendido que el siguiente fragmento guardara todo el stdout:
class Tee(object):
def __init__(self):
self.file = open('consolelog.dat', 'a')
self.stdout = sys.stdout
def __del__(self):
sys.stdout = self.stdout
self.file.close()
def write(self, data):
self.file.write(data)
self.stdout.write(data)
sys.stdout = Tee()
Mi (roto) intento de llevar todo esto junto a continuación, fue crear un objeto LoggedConsole
, y pasarlo Tee
en los locales.
console = LoggedConsole(locals={sys.stdout:LoggedExec()})
console.interact()
(yo no he pasado los locales antes, por eso lo estoy haciendo mal aquí, pero no recibo un error.)
De todas formas, esto abrirá una nueva consola interactiva, y registrará (después de cerrar) todas las entradas y errores, pero no la salida. He estado golpeando mi cabeza contra esto por un tiempo, y siento que estoy cerca, pero tal vez ni siquiera.
Además, ¿hay alguna manera de que todo esto ocurra durante la sesión? Actualmente, todo el registro tiene lugar una vez que se cierra la sesión.
Gracias por su tiempo, disculpe el muro de texto.
editar: Me gustaría poder lograr esto en el intérprete estándar de Python con fines de portabilidad.
edit2: Jaime's snippet funciona muy bien para registrar todo lo que necesito. De todos modos, ¿puedo hacerlo en tiempo real, en lugar de esperar a que la sesión se cierre?
edit3: Lo entendí :). La final, fragmento de trabajo:
import code
import sys
class Tee(object):
def __init__(self, log_fname, mode='a'):
self.log = open(log_fname, mode)
def __del__(self):
# Restore sin, so, se
sys.stdout = sys.__stdout__
sys.stdir = sys.__stdin__
sys.stderr = sys.__stderr__
self.log.close()
def write(self, data):
self.log.write(data)
self.log.flush()
sys.__stdout__.write(data)
sys.__stdout__.flush()
def readline(self):
s = sys.__stdin__.readline()
sys.__stdin__.flush()
self.log.write(s)
self.log.flush()
return s
def flush(foo):
return
sys.stdout = sys.stderr = sys.stdin = Tee('consolelog.dat', 'w')
console = code.InteractiveConsole()
console.interact()
BTW no estoy seguro de cuál es su caso de uso, pero 'ipython notebook' es una gran adición a un flujo de trabajo interactivo, en caso de que aún no lo haya visto. – Kos