vim 丢失了重要的.py文件(被覆盖为0字节文件),但旧版本仍然作为模块加载在ipython中--它可以被检索吗?

vfh0ocws  于 2023-10-20  发布在  Python
关注(0)|答案(3)|浏览(154)

在管理几个不同的屏幕会话时,其中许多都打开了Vim,在试图“组织”我的会话的过程中,我不知何故设法用一个0 Byte文件覆盖了一个非常重要的.py脚本。
然而,我有一个打开的ipython示例,当运行相同的.py文件作为一个模块时,仍然记得曾经在那里的代码!
那么,我是否刚刚学到了关于备份的一个艰难的教训(我的最后一个备份是大约一周前由Vim完成的,这会给我留下很多工作要做),或者有任何可能的,可以想象的方法来从已经加载的模块中检索.py文件?我这么傲慢也许是活该,但我真的很绝望。

6mzjoqzu

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

>>> 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!'

但是,没有-我不知道任何更直接的方法来采取一个模块,并获得源代码回来。

kulphzqa

kulphzqa2#

在进程仍在运行的情况下,您可以查看您的命名空间以查找要恢复的候选项:

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'readline', 'rlcompleter', '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使用对象缓存):

$ python -V
Python 2.7.10

$ ls | grep test
$
uplii1fm

uplii1fm3#

您应该可以使用inspect
在Ipython会话中导入inspect,假设您试图恢复myModule,请执行以下操作:
q = inspect.getsource(myModule)
q写入文件。
[编辑]这对我来说很有效,我用Python 2.7.6,IPython 1.2.1模拟了这个问题
[Edit#2]

相关问题