>> def spam():
... print("top secret function")
...
>>> print(spam)
<function spam at 0x7feccc97fb78>
>>> spam = "spam"
所以我失去了对spam
功能的引用。我可以从该内存地址取回它:0x7feccc97fb78?
>>> orig_spam_function = get_orig_func_from_memory_address("0x7feccc97fb78")
修改(回应thefourtheye ):
对于这个糟糕的问题,请考虑一下这个案例:
>>> from collections import defaultdict
>>> d = defaultdict(spam)
>>> d
defaultdict(<function spam at 0x7f597572c270>, {})
因此该函数尚未被收集。我可以恢复吗?当然,在这种情况下,您可以使用default_factory
属性。
>>> d.default_factory
<function spam at 0x7f597572c270>
但请设想defaultdict
没有default_factory
属性。
答案 0 :(得分:3)
分配时
spam = "spam"
对spam
函数的最后一次引用消失了,引用计数变为0,稍后将对其进行垃圾回收。所以,没有办法,我们可以把它拿回来。我们可以通过这个程序来检查
def spam():
print("top secret function")
import sys
print id(spam), sys.getrefcount(spam)
spam = "spam"
print id(spam), sys.getrefcount(spam)
我机器上的输出
140068817052928 2
140068817075440 12
spam
的实际地址与我们在赋值语句后看到的地址不同。所以,它现在指向一个不同的对象。但是,最初,引用计数为1(getrefcount
始终为one higher than the actual count)。当我们重新分配spam
时,现在没有人真正指向该功能。因此,它将为垃圾收集做好准备。
答案 1 :(得分:3)
@thefourtheye提出了关于垃圾收集功能的一个好点。
但是如果该函数没有被垃圾收集,你可以在所有现有对象中查找它:
def spam():
pass
spam2 = spam # keep a reference
print spam
=> <function spam at 0x56d69b0>
import gc
[ obj for obj in gc.get_objects() if id(obj) == 0x56d69b0 ]
=> [<function __main__.spam>]
这不是一种有效的方法(扫描内存中的所有对象),但它是 a 方式。
答案 2 :(得分:0)
从取证的角度来看,你可能会在分配操作后直接冻结执行,然后在内存中检查该位置,(如果你知道如何解析python内存结构)如果你小心你可能能够爬上你的方法回到一些操作代码指令,从那些你可能可以手工重写函数或类似的东西。