Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 如何使用ruamel.YAML从YAML文件加载Python lambda表达式?_Python 3.x_Serialization_Lambda_Yaml_Ruamel.yaml - Fatal编程技术网

Python 3.x 如何使用ruamel.YAML从YAML文件加载Python lambda表达式?

Python 3.x 如何使用ruamel.YAML从YAML文件加载Python lambda表达式?,python-3.x,serialization,lambda,yaml,ruamel.yaml,Python 3.x,Serialization,Lambda,Yaml,Ruamel.yaml,我正在尝试使用ruamel.yaml对包含lambda表达式的对象进行序列化和反序列化。如示例所示,这将产生一个构造函数错误。如何做到这一点 import sys import ruamel.yaml yaml = ruamel.yaml.YAML(typ='unsafe') yaml.allow_unicode = True yaml.default_flow_style = False foo = lambda x: x * 2 yaml.dump({'foo': foo}, sys.s

我正在尝试使用
ruamel.yaml
对包含lambda表达式的对象进行序列化和反序列化。如示例所示,这将产生一个
构造函数错误
。如何做到这一点

import sys
import ruamel.yaml

yaml = ruamel.yaml.YAML(typ='unsafe')
yaml.allow_unicode = True
yaml.default_flow_style = False

foo = lambda x: x * 2
yaml.dump({'foo': foo}, sys.stdout)
# foo: !!python/name:__main__.%3Clambda%3E

yaml.load('foo: !!python/name:__main__.%3Clambda%3E')
# ConstructorError: while constructing a Python object
# cannot find '<lambda>' in the module '__main__'
#   in "<unicode string>", line 1, column 6
导入系统 进口ruamel.yaml yaml=ruamel.yaml.yaml(典型='不安全') yaml.allow_unicode=True yaml.default\u flow\u style=False foo=λx:x*2 yaml.dump({'foo':foo},sys.stdout) #福:!!python/名称:_main__.%3Clambda%3E 加载('foo:!!python/name:_u main__uu.%3Clambda%3E')) #构造函数错误:在构造Python对象时 #在模块“”中找不到“” #在“”中,第1行第6列
这是行不通的。ruamel.yaml转储函数(或方法),方法是通过引用源代码中的函数名来引用这些函数(即,它不尝试存储实际代码)

您的
lambda
是一个匿名函数,因此没有可以正确检索的名称。同样,Python不支持
lambda

我不确定尝试并转储
lambda
是否是一个错误,或者是否应该发出警告


简单的解决方案是将
lambda
(s)转换为命名函数。或者,您可以访问lambda的实际代码或AST并存储和检索该代码,但这将需要更多的工作,并且可能无法移植,具体取决于您存储的内容。

感谢您的回复!存储实际代码将提供更可读的YAML文件,但如果不假设全局名称空间(例如导入的包),则几乎不可能反序列化。只要Python代码不变,我就可以存储反序列化的引用。难道不可能将lambda序列化为
!!python/name:module.scope.lambda_n
其中
n
引用了此作用域中的哪个lambda?是的,会有更多的假设,但您仍然可以存储模块名称(与类和函数一样),加载模块(即解析全局命名空间的所有合理假设)。IIRC lambda有一个唯一的id,该id不基于其(字符串)内容,但即使在同一Python版本上运行,也会有所不同。所以
似乎是更好的方法。另一件事,我想看看<代码> CurrdCukle 和 DIL/<代码>他们如何选择LAMBDAS(以及那些包的限制)。再次感谢。是否可以使用
dill
的lambda序列化和反序列化作为
ruamel.yaml
的自定义代表和构造函数?是的,我认为这是可能的。您需要在representer中区分“普通”函数和lambda,然后dill将lambda pickle为二进制(或者更好,当dill支持protocol=1时,为字符串表示),并将其作为参数写入标记`!!python/lambda“”(并不像我前面的评论那样将lambda内容作为标记的一部分)。pickle的二进制表示法需要更多的工作才能编码为ASCII/UTF-8(例如base64编码)。你需要反过来才能再次加载它。