2012-08-24 18 views
12

¿Hay alguna forma de obtener la salida dis.dis() sin redirigir sys.stdout? He tratado:capturando dis.dis resultados

out=str(dis.dis()) 

y

out="""""" 
out+=str(dis.dis()) 

Sin embargo pronto me di cuenta de que devuelve None. ¿Hay alguna forma de arreglar esto?

+0

¿Por qué no desea redirigir la salida estándar (temporalmente), como en [esta pregunta] (http://stackoverflow.com/questions/1218933/can-i-redirect-the-stdout-in-python-into-sort-of-string-buffer)? –

+0

Para Python 3.4 o posterior, hay otras soluciones. Ver [esta pregunta] (http://stackoverflow.com/q/31347044/3004881). –

Respuesta

21

Desafortunadamente, en las versiones de Python anteriores a la 3.4 el módulo dis usa declaraciones de impresión para stdout, por lo que no devolverá nada directamente útil. Ya sea que tenga que volver a poner en práctica las funciones dis, disassemble y disassemble_string, o se reemplaza temporalmente sys.stdout con una alternativa para capturar la salida:

import sys 
from cStringIO import StringIO 

out = StringIO() 
stdout = sys.stdout 
sys.stdout = out 
try: 
    dis.dis() 
finally: 
    sys.stdout = stdout 
out = out.getvalue() 

Esto es en realidad el mejor hecho usando un gestor de contexto:

import sys 
from contextlib import contextmanager 
from cStringIO import StringIO 

@contextmanager 
def captureStdOut(output): 
    stdout = sys.stdout 
    sys.stdout = output 
    try: 
     yield 
    finally: 
     sys.stdout = stdout 

out = StringIO() 
with captureStdOut(out): 
    dis.dis() 
print out.getvalue() 

De esta manera, se garantiza que tendrá stdout restaurado incluso si algo sale mal con dis. Una pequeña demostración:

>>> out = StringIO() 
>>> with captureStdOut(out): 
...  dis.dis(captureStdOut) 
... 
>>> print out.getvalue() 
83   0 LOAD_GLOBAL    0 (GeneratorContextManager) 
       3 LOAD_DEREF    0 (func) 
       6 LOAD_FAST    0 (args) 
       9 LOAD_FAST    1 (kwds) 
      12 CALL_FUNCTION_VAR_KW  0 
      15 CALL_FUNCTION   1 
      18 RETURN_VALUE   

En Python 3.4 y arriba, las funciones pertinentes a echar un parámetro file para redirigir la salida a:

from io import StringIO 

with StringIO() as out: 
    dis.dis(file=out) 
    print(out.get_value()) 
+0

(+1): Usar el administrador de contexto aquí es genio. Hermosa. – mgilson

+0

No creo que deba guardar 'sys.stdout' en la mayoría de los casos, solo puede restaurarlo usando' sys._stdout'. – agf

+0

@agf: eso supone que 'sys.stdout' no ha sido reemplazado ..' sys .__ stdout__' es el valor * predeterminado * para 'sys.stdout', pero eso no significa que' sys.stdout' es * actualmente * establecer a ese valor. –

Cuestiones relacionadas