Получение результатов dis.dis

Есть ли способ получить вывод dis.dis() без перенаправления sys.stdout? Я пробовал:

out=str(dis.dis())

и

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

Однако вскоре я узнал, что он возвращает None. Есть ли способ исправить это?

Ответ 1

К сожалению, в версиях Python до 3.4 модуль dis использует инструкции print для stdout, поэтому он не будет возвращать ничего полезного. Либо вы должны повторно реализовать функции dis, disassemble и disassemble_string, либо временно заменить sys.stdout альтернативой захвату вывода:

import sys
from cStringIO import StringIO

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

Это лучше всего сделать с помощью диспетчера контекстов:

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()

Таким образом, вы гарантированно восстановите stdout, даже если что-то пойдет не так с dis. Небольшая демонстрация:

>>> 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        

В Python 3.4 и выше соответствующие функции принимают параметр file для перенаправления вывода на:

from io import StringIO

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