python - python 中的 Pickle 和 exec

标签 python exec eval pickle

大家好!

我要做的是:

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__'中),但在后一种情况下,它在位于'__main__'的字典中我认为如果你可以告诉python该功能的真正模块方向,它将起作用。

谢谢!

最佳答案

pickle根据名称 pickle 的功能。它没有尝试转储和恢复字节码,而是只是说“好吧,这个函数是 __main__.f ,所以要取消它,请查看 __main__ 模块并检索名为 f 的东西”。这是非常有必要的;如果你 unpickle 一个函数 f在解释器环境中 f不存在或做了不同的事情,那么为了保留未 pickle 函数的原始行为,您需要以某种方式保留它引用的所有函数,它使用的所有模块,所有不再存在的全局变量等等。您需要确保递归引用 f里面f使用 unpickled 函数代替新解释器的 f ,这一切都变得一团糟。

重点是,pickle 函数必须是全局的。如果您查看其 __module__ 指定的模块并寻找由其 __name__ 命名的东西,你必须找到这个函数,否则你无法解开它。因此,您不能exec假全局字典中的函数定义,以及执行您想要 pickle 的函数的定义是一种非常容易出错的操作。

关于python - python 中的 Pickle 和 exec,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31191947/

相关文章:

python - 使用python对数据库记录进行Levenshtein的实现

python - 在颜色条周围添加黑框

javascript - 为什么 Javascript Eval 在不应该的时候变慢

python - 带有传统除号 (÷) 的 eval() 问题

linux - Bash中的 'eval'命令及其典型用途

python - 将一个数字与另一个数字的最后 n 位进行匹配

python - 按数值对 CSV 文件进行排序

php - 如何使用php在根目录上方创建文件夹

php - 使用 php 执行外部程序(如 skype.exe)

kubernetes - 为 kubernetes 集群创建的新服务帐户无法执行到 Pod 中