大家好!

我要做的是:

import pickle

exec "def f():    print 'Hi!'"
code = pickle.dumps(f)

print code


如您所见,它工作正常。

但是,为了避免定义全局变量(例如,先前代码中的f),我想执行以下操作:

import pickle

d = {}
exec "def f():    print 'Hi!'" in d
d['f']()

code = pickle.dumps(d['f'])
print code


它输出“ Hi!”,这意味着python将d ['f']识别为一个函数,但无法对其进行腌制。

您对如何执行此操作有任何想法吗?
我认为这是因为在前一种情况下,python知道在哪里可以找到该函数(在'__main__'中),但是在后一种情况下,它位于'__main__'中的字典中。我认为,如果您可以告诉python此功能的实际模块方向,它将起作用。

谢谢!

最佳答案

pickle泡菜按名称起作用。与其尝试转储和恢复字节码,不如说“好吧,此功能为__main__.f,因此要对其进行修补,请查看__main__模块并检索名为f的内容。这非常有必要;如果您在不存在f或执行其他操作的解释器环境中释放函数f,则要保留该未释放函数的原始行为,您需要以某种方式保留其引用的所有函数,它使用的模块,不再存在的所有全局变量等。您需要确保在f中对f的递归引用使用未选取的函数,而不是新解释器的f,一切都变得糟透了。

关键是腌制的功能必须是全局的。如果您查看他们的__module__指定的模块并寻找他们的__name__命名的东西,则必须找到该函数,否则将无法对其进行修补。因此,您不能在伪造的全局字典中使用exec函数定义,而您想腌制的函数的执行定义完全是容易出错的操作。

10-06 13:47
查看更多