pyyaml safe_load: 如何忽略本地标签
pyyaml safe_load: how to ignore local tags
我正在使用 yaml.safe_load()
但我需要忽略标签 !v2
-- 有没有办法做到这一点但仍然使用 safe_load()
?
我想通了,跟How can I add a python tuple to a YAML file using pyYAML?
有关
我只需要这样做:
- 子类
yaml.SafeLoader
- 调用
add_constructor
将!v2
赋值给自定义构造方法
- 在自定义构造方法中,做任何合适的事情
- 使用
yaml.load(..., MyLoaderClass)
代替yaml.safe_load(...)
而且有效。
class V2Loader(yaml.SafeLoader):
def let_v2_through(self, node):
return self.construct_mapping(node)
V2Loader.add_constructor(
u'!v2',
V2Loader.let_v2_through)
....
y = yaml.load(info, Loader=V2Loader)
扩展现有答案以支持忽略所有未知标签。
import yaml
class SafeLoaderIgnoreUnknown(yaml.SafeLoader):
def ignore_unknown(self, node):
return None
SafeLoaderIgnoreUnknown.add_constructor(None, SafeLoaderIgnoreUnknown.ignore_unknown)
root = yaml.load(content, Loader=SafeLoaderIgnoreUnknown)
的问题在于它仅适用于 v2
标签,并且仅当它所在的 yaml 对象是映射类型对象时才有效。
适用于所有标签,但问题是数据将被完全忽略。您只会得到一个 null
的数据。
如果您想忽略对所有标签的任何特殊处理,但仍然像标签不存在一样解析值,则以下方法应该有效:
def unknown(loader, suffix, node):
if isinstance(node, yaml.ScalarNode):
constructor = loader.__class__.construct_scalar
elif isinstance(node, yaml.SequenceNode):
constructor = loader.__class__.construct_sequence
elif isinstance(node, yaml.MappingNode):
constructor = loader.__class__.construct_mapping
data = constructor(loader, node)
return data
yaml.add_multi_constructor('!', unknown)
yaml.add_multi_constructor('tag:', unknown)
return yaml.load_all(infile, Loader=yaml.FullLoader)
请注意,如果您想使用不同的加载程序,例如 SafeLoader,您需要在调用加载函数之前明确向 add_multi_constructor() 提供加载程序:
yaml.add_multi_constructor('!', unknown, Loader=yaml.SafeLoader)
...
return yaml.load_all(infile, Loader=yaml.SafeLoader)
我正在使用 yaml.safe_load()
但我需要忽略标签 !v2
-- 有没有办法做到这一点但仍然使用 safe_load()
?
我想通了,跟How can I add a python tuple to a YAML file using pyYAML?
有关我只需要这样做:
- 子类
yaml.SafeLoader
- 调用
add_constructor
将!v2
赋值给自定义构造方法 - 在自定义构造方法中,做任何合适的事情
- 使用
yaml.load(..., MyLoaderClass)
代替yaml.safe_load(...)
而且有效。
class V2Loader(yaml.SafeLoader):
def let_v2_through(self, node):
return self.construct_mapping(node)
V2Loader.add_constructor(
u'!v2',
V2Loader.let_v2_through)
....
y = yaml.load(info, Loader=V2Loader)
扩展现有答案以支持忽略所有未知标签。
import yaml
class SafeLoaderIgnoreUnknown(yaml.SafeLoader):
def ignore_unknown(self, node):
return None
SafeLoaderIgnoreUnknown.add_constructor(None, SafeLoaderIgnoreUnknown.ignore_unknown)
root = yaml.load(content, Loader=SafeLoaderIgnoreUnknown)
v2
标签,并且仅当它所在的 yaml 对象是映射类型对象时才有效。
null
的数据。
如果您想忽略对所有标签的任何特殊处理,但仍然像标签不存在一样解析值,则以下方法应该有效:
def unknown(loader, suffix, node):
if isinstance(node, yaml.ScalarNode):
constructor = loader.__class__.construct_scalar
elif isinstance(node, yaml.SequenceNode):
constructor = loader.__class__.construct_sequence
elif isinstance(node, yaml.MappingNode):
constructor = loader.__class__.construct_mapping
data = constructor(loader, node)
return data
yaml.add_multi_constructor('!', unknown)
yaml.add_multi_constructor('tag:', unknown)
return yaml.load_all(infile, Loader=yaml.FullLoader)
请注意,如果您想使用不同的加载程序,例如 SafeLoader,您需要在调用加载函数之前明确向 add_multi_constructor() 提供加载程序:
yaml.add_multi_constructor('!', unknown, Loader=yaml.SafeLoader)
...
return yaml.load_all(infile, Loader=yaml.SafeLoader)