您不是在寻找错误的关键字,这不是我所知道的任何 YAML 解析器要做的事情。 YAML 解析器加载一个可能很复杂的自包含数据结构。您要做的是在其中一个解析步骤中将该自包含结构合并到一个已经存在的结构中(lut)。解析器旨在通过提供替代例程而不是通过提供例程+数据
来进行调整
PyYAML 中没有内置的选项,即没有内置的方法告诉加载器lut 使 PyYAML 对其进行处理,当然也不会附加键值对(假设是你对节点的意思)作为其键的值。
获得所需内容的最简单方法可能是使用一些后期处理,该处理采用 lut 和从 YAML 文件(也是一个字典)加载的数据并将两者结合起来。
如果您想尝试使用add_constructor 执行此操作,那么您需要做的是使用__call__ 方法构造一个类,使用lut 作为参数创建该类的实例,然后传递该实例in 作为替代构造函数):
class ConstructorWithLut:
def __init__(self, lut):
self._lut = lut
def __call__(self):
# the actual constructor routine added by add_constructor
constructor_with_lut(lut)
SomeConstructor.add_constructor('your_tag', constructor_with_lut)
如果需要,您可以在其中将 'your_tag' 替换为 u'tag:yaml.org,2002:map'
您的构造函数来处理(所有)普通字典。
另一种选择是在 YAML 加载期间执行此操作,但您不能再一次调整 Loader 或其组成组件之一(Constructor),因为您通常提交类而不是对象。您需要一个能够附加lut 的对象。因此,您要做的是创建自己的构造函数和使用该构造函数的加载器,然后使用 load() 替换来实例化加载器,附加 lut(只需将其添加为唯一属性,或将其传入作为参数并将其传递给您的构造函数)。
您的构造函数应该是现有构造函数之一的子类,然后必须有自己的construct_mapping(),它首先调用父类'construct_mapping(),并且在返回结果之前,检查它是否可以更新它已分配lut 的属性。您不能基于查看foo 的字典键来执行此操作,因为如果您有这样的键,则您无权访问需要分配给@987654338 的父节点@。您需要做的是查看映射的任何值是否是具有键名foo 的字典,如果是,则可以使用字典根据与foo 关联的值更新lut .
我当然会首先使用两个例程来实现后期处理阶段:
def update_from_yaml(your_dict, yaml_data):
for node_key in yaml_data:
node_value = yaml_data[node_key]
map_value(your_dict, node_key, node_value)
def map_value(your_dict, key, value):
foo_val = value.get('foo')
if foo_val is None: # key foo not found
return
your_dict[foo_val] = value # or = {key: value}
我不确定“分配所有 foo 节点”的真正含义,YAML 数据在顶层没有节点,它只有键和值。所以你要么分配那对,要么只分配它的值(一个字典)。
一旦这两个例程工作令人满意,您可以尝试实现基于add_constructor 或Loader 的替代方案,其中您至少应该能够重复使用map_value