在 python 中选择并执行
Pickle and exec in python
¡大家好!
我要做的是:
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']识别为一个函数,但它不能pickle它。
你知道怎么做吗?
我认为这是因为在前一种情况下,python 知道在哪里可以找到该函数(它在“__main__”中),但在后一种情况下,它在位于“[=29”的字典中=]' 我觉得如果你能告诉python这个函数真正的模块方向,就可以了。
谢谢!
pickle
按名称腌制函数。它没有尝试转储和恢复字节码,而是说 "okay, this function is __main__.f
, so to unpickle it, look in the __main__
module and retrieve the thing called f
"。这几乎是必要的;如果您在 f
不存在的解释器环境中取消函数 f
或做一些不同的事情,那么为了保留取消函数的原始行为,您需要以某种方式保留所有函数它引用,它使用的所有模块,所有不再存在的全局变量等。您需要确保 f
内部对 f
的递归引用使用 unpickled 函数新解释器的f
,这一切都变得一团糟。
关键在于 pickled 函数 是全局的。如果你在他们的 __module__
指定的模块中寻找他们的 __name__
命名的东西,你必须找到函数,否则你无法解开它。因此,您不能 exec
伪造的全局字典中的函数定义,并且执行您想要 pickle 的函数定义是一个非常容易出错的操作。
我在这里找到了一个非常好的解决方案:
Dynamically importing Python module
解决上述问题的代码是这样的:
import pickle
import sys
import imp
foo = imp.new_module("foo")
sys.modules["foo"] = foo
exec "def f(): print 'Hi!'" in foo.__dict__
code = pickle.dumps(foo.f)
print code
如你所见,解决方案是构建一个新模块,函数将被 pickleable
¡大家好!
我要做的是:
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']识别为一个函数,但它不能pickle它。
你知道怎么做吗? 我认为这是因为在前一种情况下,python 知道在哪里可以找到该函数(它在“__main__”中),但在后一种情况下,它在位于“[=29”的字典中=]' 我觉得如果你能告诉python这个函数真正的模块方向,就可以了。
谢谢!
pickle
按名称腌制函数。它没有尝试转储和恢复字节码,而是说 "okay, this function is __main__.f
, so to unpickle it, look in the __main__
module and retrieve the thing called f
"。这几乎是必要的;如果您在 f
不存在的解释器环境中取消函数 f
或做一些不同的事情,那么为了保留取消函数的原始行为,您需要以某种方式保留所有函数它引用,它使用的所有模块,所有不再存在的全局变量等。您需要确保 f
内部对 f
的递归引用使用 unpickled 函数新解释器的f
,这一切都变得一团糟。
关键在于 pickled 函数 是全局的。如果你在他们的 __module__
指定的模块中寻找他们的 __name__
命名的东西,你必须找到函数,否则你无法解开它。因此,您不能 exec
伪造的全局字典中的函数定义,并且执行您想要 pickle 的函数定义是一个非常容易出错的操作。
我在这里找到了一个非常好的解决方案: Dynamically importing Python module
解决上述问题的代码是这样的:
import pickle
import sys
import imp
foo = imp.new_module("foo")
sys.modules["foo"] = foo
exec "def f(): print 'Hi!'" in foo.__dict__
code = pickle.dumps(foo.f)
print code
如你所见,解决方案是构建一个新模块,函数将被 pickleable