ruamel.yaml 可以支持像 "num: !!float 4" 这样的类型描述符吗?
Could ruamel.yaml support type descriptor like "num: !!float 4"?
我正在学习使用 ruamel.yaml
,我想知道它是否支持像“num: !!float 4”这样的原始 YAML 类型描述符?
文件如下:
num: !!float 4
我尝试导入这样的文件,但遇到错误:
---------------------------------------------------------------------------<br>
ValueError Traceback (most recent call last)
Input In [22], in <cell line: 2>()
1 from ruamel import yaml
2 with open("net.yaml", "r", encoding="utf-8") as yaml_file:
----> 3 yaml_dict = yaml.round_trip_load(yaml_file)
4 yaml_dict
...
File ~/software/python/anaconda/anaconda3/envs/conda-general/lib/python3.10/site-packages/ruamel/yaml/constructor.py:1469, in RoundTripConstructor.construct_mapping(self, node, maptyp, deep)
1462 if not isinstance(key, Hashable):
1463 raise ConstructorError(
1464 'while constructing a mapping',
1465 node.start_mark,
1466 'found unhashable key',
1467 key_node.start_mark,
1468 )
-> 1469 value = self.construct_object(value_node, deep=deep)
1470 if self.check_mapping_key(node, key_node, maptyp, key, value):
1471 if key_node.comment and len(key_node.comment) > 4 and key_node.comment[4]:
File ~/software/python/anaconda/anaconda3/envs/conda-general/lib/python3.10/site-packages/ruamel/yaml/constructor.py:146, in BaseConstructor.construct_object(self, node, deep)
142 # raise ConstructorError(
143 # None, None, 'found unconstructable recursive node', node.start_mark
144 # )
145 self.recursive_objects[node] = None
--> 146 data = self.construct_non_recursive_object(node)
148 self.constructed_objects[node] = data
149 del self.recursive_objects[node]
File ~/software/python/anaconda/anaconda3/envs/conda-general/lib/python3.10/site-packages/ruamel/yaml/constructor.py:181, in BaseConstructor.construct_non_recursive_object(self, node, tag)
179 constructor = self.__class__.construct_mapping
180 if tag_suffix is None:
--> 181 data = constructor(self, node)
182 else:
183 data = constructor(self, tag_suffix, node)
File ~/software/python/anaconda/anaconda3/envs/conda-general/lib/python3.10/site-packages/ruamel/yaml/constructor.py:1271, in RoundTripConstructor.construct_yaml_float(self, node)
1259 return ScalarFloat(
1260 sign * float(value_s),
1261 width=width,
(...)
1268 anchor=node.anchor,
1269 )
1270 width = len(value_so)
-> 1271 prec = value_so.index('.') # you can use index, this would not be float without dot
1272 lead0 = leading_zeros(value_so)
1273 return ScalarFloat(
1274 sign * float(value_s),
1275 width=width,
(...)
1279 anchor=node.anchor,
1280 )
ValueError: substring not found
为什么会出现此错误,如何消除它?
这是 ruamel.yaml<=0.17.21
中的错误。对违规行 (1271) 的评论说
# you can use index, this would not be float without dot
显然该评论的作者不知道他在说什么,就像您的情况一样,当使用 !!float 4
时,您有一个没有点的浮点数...
通过在第 1271 行用 find
替换 index
来“修复”这个问题是微不足道的,这样做会加载您的文档并且您可以转储数据。
但是相应的转储表示不处理将浮点数输出为 4.0
,删除标签。
您可以通过注册一个更简单的 float 构造函数(例如来自 SafeLoader 的简单构造函数)临时解决此问题,尽管这会影响所有 float:
import sys
import ruamel.yaml
yaml_str = """\
num: !!float 4
"""
yaml = ruamel.yaml.YAML()
yaml.constructor.add_constructor(
'tag:yaml.org,2002:float', ruamel.yaml.constructor.SafeConstructor.construct_yaml_float
)
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
给出:
num: 4.0
我正在学习使用 ruamel.yaml
,我想知道它是否支持像“num: !!float 4”这样的原始 YAML 类型描述符?
文件如下:
num: !!float 4
我尝试导入这样的文件,但遇到错误:
---------------------------------------------------------------------------<br> ValueError Traceback (most recent call last) Input In [22], in <cell line: 2>() 1 from ruamel import yaml 2 with open("net.yaml", "r", encoding="utf-8") as yaml_file: ----> 3 yaml_dict = yaml.round_trip_load(yaml_file) 4 yaml_dict ... File ~/software/python/anaconda/anaconda3/envs/conda-general/lib/python3.10/site-packages/ruamel/yaml/constructor.py:1469, in RoundTripConstructor.construct_mapping(self, node, maptyp, deep) 1462 if not isinstance(key, Hashable): 1463 raise ConstructorError( 1464 'while constructing a mapping', 1465 node.start_mark, 1466 'found unhashable key', 1467 key_node.start_mark, 1468 ) -> 1469 value = self.construct_object(value_node, deep=deep) 1470 if self.check_mapping_key(node, key_node, maptyp, key, value): 1471 if key_node.comment and len(key_node.comment) > 4 and key_node.comment[4]: File ~/software/python/anaconda/anaconda3/envs/conda-general/lib/python3.10/site-packages/ruamel/yaml/constructor.py:146, in BaseConstructor.construct_object(self, node, deep) 142 # raise ConstructorError( 143 # None, None, 'found unconstructable recursive node', node.start_mark 144 # ) 145 self.recursive_objects[node] = None --> 146 data = self.construct_non_recursive_object(node) 148 self.constructed_objects[node] = data 149 del self.recursive_objects[node] File ~/software/python/anaconda/anaconda3/envs/conda-general/lib/python3.10/site-packages/ruamel/yaml/constructor.py:181, in BaseConstructor.construct_non_recursive_object(self, node, tag) 179 constructor = self.__class__.construct_mapping 180 if tag_suffix is None: --> 181 data = constructor(self, node) 182 else: 183 data = constructor(self, tag_suffix, node) File ~/software/python/anaconda/anaconda3/envs/conda-general/lib/python3.10/site-packages/ruamel/yaml/constructor.py:1271, in RoundTripConstructor.construct_yaml_float(self, node) 1259 return ScalarFloat( 1260 sign * float(value_s), 1261 width=width, (...) 1268 anchor=node.anchor, 1269 ) 1270 width = len(value_so) -> 1271 prec = value_so.index('.') # you can use index, this would not be float without dot 1272 lead0 = leading_zeros(value_so) 1273 return ScalarFloat( 1274 sign * float(value_s), 1275 width=width, (...) 1279 anchor=node.anchor, 1280 ) ValueError: substring not found
为什么会出现此错误,如何消除它?
这是 ruamel.yaml<=0.17.21
中的错误。对违规行 (1271) 的评论说
# you can use index, this would not be float without dot
显然该评论的作者不知道他在说什么,就像您的情况一样,当使用 !!float 4
时,您有一个没有点的浮点数...
通过在第 1271 行用 find
替换 index
来“修复”这个问题是微不足道的,这样做会加载您的文档并且您可以转储数据。
但是相应的转储表示不处理将浮点数输出为 4.0
,删除标签。
您可以通过注册一个更简单的 float 构造函数(例如来自 SafeLoader 的简单构造函数)临时解决此问题,尽管这会影响所有 float:
import sys
import ruamel.yaml
yaml_str = """\
num: !!float 4
"""
yaml = ruamel.yaml.YAML()
yaml.constructor.add_constructor(
'tag:yaml.org,2002:float', ruamel.yaml.constructor.SafeConstructor.construct_yaml_float
)
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
给出:
num: 4.0