gpt4 book ai didi

python - 通过 PyYAML 序列化命名元组

转载 作者:太空宇宙 更新时间:2023-11-04 06:01:30 25 4
gpt4 key购买 nike

我正在寻找一些合理的方法来使用 PyYAML 在 YAML 中序列化命名元组。

一些我不想做的事情:

  • 依靠动态调用在命名元组实例化时添加构造函数/表示器/解析器。这些 YAML 文件可能会被存储并在以后重新加载,因此我不能依赖它们恢复时存在的相同运行时环境。

  • 在全局注册命名元组。

  • 依靠具有唯一名称的命名元组

我在想一些类似的事情:

class namedtuple(object):
def __new__(cls, *args, **kwargs):
x = collections.namedtuple(*args, **kwargs)

class New(x):
def __getstate__(self):
return {
"name": self.__class__.__name__,
"_fields": self._fields,
"values": self._asdict().values()
}
return New

def namedtuple_constructor(loader, node):
import IPython; IPython.embed()
value = loader.construct_scalar(node)

import re
pattern = re.compile(r'!!python/object/new:myapp.util\.')
yaml.add_implicit_resolver(u'!!myapp.util.namedtuple', pattern)
yaml.add_constructor(u'!!myapp.util.namedtuple', namedtuple_constructor)

假设这是在路径 myapp/util.py 的应用程序模块中

但是,当我尝试加载时,我没有进入构造函数:

from myapp.util import namedtuple

x = namedtuple('test', ['a', 'b'])
t = x(1,2)
dump = yaml.dump(t)
load = yaml.load(dump)

它将无法在 myapp.util 中找到 New。

我也尝试了多种其他方法,这只是我认为可能效果最好的一种。

免责声明:即使我进入了正确的构造函数,我也知道我的规范需要进一步研究保存哪些参数,如何将它们传递到结果对象中,但对我来说,第一步是将 YAML 表示形式放入我的构造函数,那么剩下的应该很容易。

最佳答案

我能够解决我的问题,尽管方式不太理想。

我的应用程序现在使用它自己的 namedtuple 实现;我复制了 collections.namedtuple 源代码,为所有要继承的新 namedtuple 类型创建了一个基类,并修改了模板(为简洁起见,下面摘录了一些内容,只是突出显示了与命名元组源)。

class namedtupleBase(tuple): 
pass

_class_template = '''\
class {typename}(namedtupleBase):
'{typename}({arg_list})'

对 namedtuple 函数本身进行一点改动,将新类添加到命名空间中:

namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
OrderedDict=OrderedDict, _property=property, _tuple=tuple,
namedtupleBase=namedtupleBase)

现在注册一个multi_representer 解决了这个问题:

def repr_namedtuples(dumper, data):
return dumper.represent_mapping(u"!namedtupleBase", {
"__name__": data.__class__.__name__,
"__dict__": collections.OrderedDict(
[(k, v) for k, v in data._asdict().items()])
})

def consruct_namedtuples(loader, node):
value = loader.construct_mapping(node)
cls_ = namedtuple(value['__name__'], value['__dict__'].keys())
return cls_(*value['__dict__'].values())

yaml.add_multi_representer(namedtupleBase, repr_namedtuples)
yaml.add_constructor("!namedtupleBase", consruct_namedtuples)

点击Represent instance of different classes with the same base class in pyyaml寻找解决方案背后的灵感。

会喜欢不需要重新创建 namedtuple 函数的想法,但这实现了我的目标。

关于python - 通过 PyYAML 序列化命名元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24717753/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com