当前位置: 首页 > 工具软件 > Stout > 使用案例 >

python中stout的重定向

孙永嘉
2023-12-01

在使用dis反编译python的时候出现一个问题,dis会直接输出反编译结果,每块代码的第一行会显示代码的行号。

#c.py
i = 1
s = 'string'
l = []
d = {}

>>> s = open('c.py').read()
>>> import dis
>>> s = open('c.py').read()
>>> co = compile(s, 'c.py', 'exec')
>>> dis.dis(co)
  1           0 LOAD_CONST               0 (1)
              3 STORE_NAME               0 (i)

  2           6 LOAD_CONST               1 ('string')
              9 STORE_NAME               1 (s)

  3          12 BUILD_LIST               0
             15 STORE_NAME               2 (l)

  4          18 BUILD_MAP                0
             21 STORE_NAME               3 (d)
             24 LOAD_CONST               2 (None)
             27 RETURN_VALUE        
>>> 

但是要是看那些字节码还得和原文件对照着看,很不爽,就有了直接输出源文件的代码,紧接着输出这行代码得字节码的想法,但是dis会直接输出结果,不能通过它获取反编译后的结果(当然你可以通过修改库文件实现,不过严重不推荐),要是能把输出的结果保存到某个变量中就好了,于是百度之。

http://leejd.cndev.org/2005/04/06/10137/找到一篇文章把输出重定向到了文件,我就试了一下。

>>> 
>>> import sys
>>> f = open('a.py','r')
>>> print(f.read())

>>> f.close()
>>> f = open('a.py', 'w+')
>>> _out = sys.stdout
>>> sys.stdout = f
>>> print('stdout to file')
>>> f.close()
>>> sys.stdout = _out
>>> f = open('a.py', 'r')
>>> print(f.read())
stdout to file

>>> 

效果不错,但是如果把输出重定向到文件岂不是还要再从文件中读取结果,那太不爽了,应该把输出重定向到某个变量:

>>> s = ''
>>> _out = sys.stdout
>>> sys.stdout = s
>>> print('stdout to string')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'write'
>>> 


它说str变量没有write属性,按照提示继续前行

>>>     
>>> import sys
>>> class stdoutToStr:
...     def __init__(self):
...             self.s = ''
...     def write(self, buf):
...             self.s += buf
... 
>>> _out = sys.stdout
>>> out = stdoutToStr()
>>> sys.stdout = out
>>> print('stdout to object')
>>> sys.stdout = _out
>>> print(out.s)
stdout to object

>>> 

ok,到现在为止,可以控制print的输出位置了,只要做一个对象,这个对象有write方法,把stdout重定向到这个对象,使用print的时候就会调用对象的write方法。

剩下的就是写个小程序实现刚开始说的问题了:

#! /usr/bin/env python
#coding=utf-8

import sys,dis

#定义标准输出对象
class stdoutToStr:
    def __init__(self):
        self.s = ''
    def write(self, buf):
        self.s += buf

#重定向标准输出
_out = sys.stdout
out = stdoutToStr()
sys.stdout = out

#指定参数
fle = sys.argv[1]
model = 'exec'

#编译文件
f = open(fle)
s = f.read()
f.close()
co = compile(s, fle, model)
dis.dis(co)

#重定向标准输出
sys.stdout = _out

#处理编译后的字节码
f = open(fle)
fLines = f.readlines()
f.close()
lines = out.s.splitlines()

for line in lines:
    lineNum = line[0:5].strip()
    if lineNum == '':
        print line
    else:
        num = int(lineNum)
        print fLines[num-1],
        print line

运行结果:

shi-kefumatoiMac:pycode shikefu678$ python byteCode.py c.py
i = 1
  1           0 LOAD_CONST               0 (1)
              3 STORE_NAME               0 (i)

s = 'string'
  2           6 LOAD_CONST               1 ('string')
              9 STORE_NAME               1 (s)

l = []
  3          12 BUILD_LIST               0
             15 STORE_NAME               2 (l)

d = {}   4          18 BUILD_MAP                0
             21 STORE_NAME               3 (d)
             24 LOAD_CONST               2 (None)
             27 RETURN_VALUE        







 类似资料: