在使用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'
>>>
>>>
>>> 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
>>>
剩下的就是写个小程序实现刚开始说的问题了:
#! /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