在管理几个不同的屏幕会话时,其中许多都打开了Vim,在试图“组织”我的会话的过程中,我不知何故设法用一个0 Byte文件覆盖了一个非常重要的.py脚本。然而,我有一个打开的ipython示例,当运行相同的.py文件作为一个模块时,仍然记得曾经在那里的代码!那么,我是否刚刚学到了关于备份的一个艰难的教训(我的最后一个备份是大约一周前由Vim完成的,这会给我留下很多工作要做),或者有任何可能的,可以想象的方法来从已经加载的模块中检索.py文件?我这么傲慢也许是活该,但我真的很绝望。
6mzjoqzu1#
正如注解中所指出的,inspect.getsource将无法工作,因为它依赖于原始文件(即module.__file__)。最佳选择:检查是否有.pyc文件(例如,foo.pyc应该在foo.py旁边)。如果有,你可以使用Decompile Python 2.7 .pyc来反编译它。inspect模块还缓存源代码。您可能会幸运地使用inspect.getsource(module),或者inspect.getsourcelines(module.function)(如果它在过去被调用过)。否则,您需要通过检查导出(即module.__globals__)来“手动”重建模块。常量和诸如此类的东西是显而易见的,对于函数,你可以使用func.func_name来获取它的名字,func.__doc__来获取文档字符串,inspect.getargspec(func)来获取参数,func.func_code来获取代码的细节:co_firstlineno将获得行号,然后co_code将获得代码。这里有更多关于反编译的内容:Exploring and decompiling python bytecode例如,要使用uncompyle2:
inspect.getsource
module.__file__
.pyc
foo.pyc
foo.py
inspect
inspect.getsource(module)
inspect.getsourcelines(module.function)
module.__globals__
func.func_name
func.__doc__
inspect.getargspec(func)
func.func_code
co_firstlineno
co_code
uncompyle2
>>> def foo(): ... print "Hello, world!" ... >>> from StringIO import StringIO >>> import uncompyle2 >>> out = StringIO() >>> uncompyle2.uncompyle("2.7", foo.func_code, out=out) >>> print out.getvalue() print 'Hello, world!'
但是,没有-我不知道任何更直接的方法来采取一个模块,并获得源代码回来。
kulphzqa2#
在进程仍在运行的情况下,您可以查看您的命名空间以查找要恢复的候选项:
>>> dir() ['__builtins__', '__doc__', '__name__', '__package__', 'readline', 'rlcompleter', 'test']
让我们来看看test的存储:
test
>>> help(test) Help on module test: NAME test FILE /Users/tfisher/code/ffi4wd/test.py FUNCTIONS call_cat(cat) DATA cat_name = 'commander sprinkles'
它的输出比查看test内部的局部变量更清晰:
>>> dir(test) ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'call_cat', 'cat_name', 'json']
使用inspect模块,我们可以获得函数的参数规格:
>>> inspect.getargspec(test.call_cat) ArgSpec(args=['cat'], varargs=None, keywords=None, defaults=None)
或者我们函数内部的行:
>>> inspect.getsourcelines(test.call_cat) (['def call_cat(cat):\n', ' print("Hello %s" % cat)\n'], 5)
与原作相当接近:
import json cat_name = 'commander sprinkles' def call_cat(cat): print("Hello %s" % cat)
如果文件在导入后被删除,并且没有被更新的同名文件替换,则应该工作(如果可能,getsourcelines使用对象缓存):
getsourcelines
$ python -V Python 2.7.10 $ ls | grep test $
uplii1fm3#
您应该可以使用inspect在Ipython会话中导入inspect,假设您试图恢复myModule,请执行以下操作:q = inspect.getsource(myModule)将q写入文件。[编辑]这对我来说很有效,我用Python 2.7.6,IPython 1.2.1模拟了这个问题[Edit#2]
myModule
q = inspect.getsource(myModule)
q
3条答案
按热度按时间6mzjoqzu1#
正如注解中所指出的,
inspect.getsource
将无法工作,因为它依赖于原始文件(即module.__file__
)。最佳选择:检查是否有
.pyc
文件(例如,foo.pyc
应该在foo.py
旁边)。如果有,你可以使用Decompile Python 2.7 .pyc来反编译它。inspect
模块还缓存源代码。您可能会幸运地使用inspect.getsource(module)
,或者inspect.getsourcelines(module.function)
(如果它在过去被调用过)。否则,您需要通过检查导出(即
module.__globals__
)来“手动”重建模块。常量和诸如此类的东西是显而易见的,对于函数,你可以使用func.func_name
来获取它的名字,func.__doc__
来获取文档字符串,inspect.getargspec(func)
来获取参数,func.func_code
来获取代码的细节:co_firstlineno
将获得行号,然后co_code
将获得代码。这里有更多关于反编译的内容:Exploring and decompiling python bytecode例如,要使用
uncompyle2
:但是,没有-我不知道任何更直接的方法来采取一个模块,并获得源代码回来。
kulphzqa2#
在进程仍在运行的情况下,您可以查看您的命名空间以查找要恢复的候选项:
让我们来看看
test
的存储:它的输出比查看
test
内部的局部变量更清晰:使用inspect模块,我们可以获得函数的参数规格:
或者我们函数内部的行:
与原作相当接近:
如果文件在导入后被删除,并且没有被更新的同名文件替换,则应该工作(如果可能,
getsourcelines
使用对象缓存):uplii1fm3#
您应该可以使用
inspect
在Ipython会话中导入
inspect
,假设您试图恢复myModule
,请执行以下操作:q = inspect.getsource(myModule)
将
q
写入文件。[编辑]这对我来说很有效,我用Python 2.7.6,IPython 1.2.1模拟了这个问题
[Edit#2]