从python解释器恢复.pyc文件
因为我是个白痴,我删除了一些python文件,但备份失败。在此之前,我打开了python解释器(即,运行从python解释器恢复.pyc文件,python,Python,因为我是个白痴,我删除了一些python文件,但备份失败。在此之前,我打开了python解释器(即,运行python),然后使用命令import myfile.py 编辑:我实际上使用了命令importmyfile,这显然更糟糕 有什么方法可以从我打开的python解释器会话中恢复.pyc(或者更好的是.py,但这似乎不可能)文件吗?inspect.getsource支持转储模块,因此您可以 import inspect inspect.getsource(myfile) 由于这似乎不起作用,
python
),然后使用命令import myfile.py
编辑:我实际上使用了命令importmyfile
,这显然更糟糕
有什么方法可以从我打开的python解释器会话中恢复.pyc(或者更好的是.py,但这似乎不可能)文件吗?
inspect.getsource
支持转储模块,因此您可以
import inspect
inspect.getsource(myfile)
由于这似乎不起作用,您至少应该能够使用
import dis
dis.dis(myfile)
字节码反编译器可以将Python2.x类、方法、函数和代码反编译为源代码(注意:via)
对于以下功能,这将非常有效:
from StringIO import StringIO
from uncompyle2 import uncompyle
from inspect import *
def decompile_function(f, indent=''):
s = StringIO()
uncompyle(2.7, f.func_code, s)
return '%sdef %s%s:\n%s %s' % (
indent,
f.func_name,
inspect.formatargspec(*inspect.getargspec(f)),
indent,
('\n ' + indent).join(''.join(s.buflist).split('\n')))
不幸的是,由于类已经执行,因此无法恢复它们的结构;您需要单独反编译这些方法,希望这样就足够了:
def decompile_class(c):
return 'class %s(%s):\n' % (
c.__name__,
','.join(b.__module__ + '.' + b.__name__ for b in c.__bases__)) + \
'\n'.join(decompile_function(m.im_func, ' ')
for n, m in inspect.getmembers(c) if inspect.ismethod(m))
完整解决方案:
def decompile_module(mod):
return '\n\n'.join(decompile_function(m) if isfunction(m) else
decompile_class(m) if isclass(m) else
'# UNKNOWN: ' + repr((n, m))
for n, m in inspect.getmembers(mod) if inspect.getmodule(m) is mod)
我认为您甚至可以
导入inspect
并执行inspect.getsource(myfile)
你的意思是你使用了导入myfile
,而不是导入myfile.py
,对吗?@abarnert.是的,这就是我的意思。你在什么平台上?详细信息与Windows vs.*nix有很大不同。@dustyrockpyle很遗憾,这产生了一个错误,正如我在另一个答案中所述。产生错误:IOError:源代码不可用。“如果模块是由.pyc
而不是.py
导入的,并且.py
文件已被删除,则此操作将不起作用。@goncalopp好的,这样我可以访问反汇编的代码。”。显然,从这里我可以更快地拼凑出我的代码的工作版本。理想情况下,我能够从中恢复python代码,但我认为这是一个有损的过程。有什么想法吗?事实上,inspect.getmembers(myfile)
对于获取所有成员应该同样有效。但这是一个聪明的想法:与其试图恢复编译后的代码并找出如何将其转储到.pyc
,不如将其返回到源代码并转储到功能等效的.py
。很好的解决方案!在我的计算机上,除非我指定了文件:unmyle.unmyle(2.7,myfile.myfunc.func_代码,open('myfile-1.py','w'))
或unmyle.unmyle(2.7,myfile.myfunc.func_代码,sys.stdout)
@goncalopp:看起来您使用的是unmyle
,而不是unmyle2
。好吧,它们都是同一个项目的分支,所以使用它们应该非常相似……但是如果有人建议一个,而你使用另一个,但它不起作用,你应该试试他建议的那个。@abarnert我确实尝试过解压,它有同样的行为。不过,StringIO是一个很好的解决方案