17

有什么方法可以在dis.dis()不重定向的情况下获得输出sys.stdout?我试过了:

out=str(dis.dis())

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

但是我很快发现它返回了None。有没有什么办法解决这一问题?

4

2 回答 2

24

不幸的是,在 3.4 之前的 Python 版本中,该dis模块使用打印语句到标准输出,因此它不会返回任何直接有用的东西。要么您必须重新实现dis,disassembledisassemble_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        

In Python 3.4 and up, the relevant functions take a file parameter to redirect output to:

from io import StringIO

with StringIO() as out:
    dis.dis(file=out)
    print(out.getvalue())
于 2012-08-24T14:55:30.417 回答
0

If using Colab / Jupyter

In one cell you can run dis redirecting the output to a variable

%%capture dis_output
# dis : Disassembler for Python bytecode
from dis import dis
dis(function_to_check)

And then you can use it from Bash. Here an example

! echo  "{dis_output.stdout}" | grep -i global

14           4 LOAD_GLOBAL              0 (AudioLibrary)
             36 LOAD_GLOBAL              2 (userLanguageAudio)
             50 LOAD_GLOBAL              2 (userLanguageAudio)
             62 LOAD_GLOBAL              3 (LESSON_FILES_DIR)
 27          76 LOAD_GLOBAL              4 (get_ipython)
 30          96 LOAD_GLOBAL              6 (pread)
 31         104 LOAD_GLOBAL              7 (print)
 34     >>  124 LOAD_GLOBAL              7 (print)

Or from Python

print(dis_output.stdout)
于 2022-02-15T16:54:00.873 回答