在转储/序列化输入中具有长行的数据时,pyyaml 添加额外的缩进和新行 - 这很烦人,我们如何避免在两行/多行中进行这种转换?
例如
In [1]: x = "-c /home/user/test/test2/test23/tet/2s/test1/stest/longdirectory1/directory2/ --optnion12 --verbose"
In [2]: import yaml
In [3]: print (yaml.dump([dict(ATTRIBUTES=[dict(CONFIG=x)])], default_flow_style=False))
错了
- ATTRIBUTES:
- CONFIG: -c /home/user/test/test2/test23/tet/2s/test1/stest/longdirectory1/directory2/
--optnion12 --verbose
应该是这样的
- ATTRIBUTES:
- CONFIG: -c /home/user/test/test2/test23/tet/2s/test1/stest/longdirectory1/directory2/ --optnion12 --verbose
感谢 @MathieuMarques 建议查看 @ dump 选项和提供的链接,YAML 文档还不够好,无法找到它。
无论如何,解决方案是为
width
函数指定 dump
参数。
即
yaml.dump(data, width=1000)
@RandomCoder建议使用
yaml.dump(data, width=float("inf"))
作为永久解决方案的更好方法。
我在 Ansible 插件中尝试了
sys.maxsize
和 float("inf")
,当我遇到错误时非常困惑。我发现使用CDumper
时,可以使用-1
的值来实现无限宽度,并且不能使用大数字。
import yaml
from yaml import Dumper, CDumper
x = [dict(ATTRIBUTES=[dict(CONFIG="-c /home/user/test/test2/test23/tet/2s/test1/stest/longdirectory1/directory2/ --optnion12 --verbose")])]
print("python dumper -1")
print(yaml.dump(x, width=-1, Dumper=Dumper))
print("python dumper inf")
print(yaml.dump(x, width=float("inf"), Dumper=Dumper))
print("C dumper -1")
print(yaml.dump(x, width=-1, Dumper=CDumper))
print("C dumper inf")
print(yaml.dump(x, width=float("inf"), Dumper=CDumper))
python dumper -1
- ATTRIBUTES:
- CONFIG: -c /home/user/test/test2/test23/tet/2s/test1/stest/longdirectory1/directory2/
--optnion12 --verbose
python dumper inf
- ATTRIBUTES:
- CONFIG: -c /home/user/test/test2/test23/tet/2s/test1/stest/longdirectory1/directory2/ --optnion12 --verbose
C dumper -1
- ATTRIBUTES:
- CONFIG: -c /home/user/test/test2/test23/tet/2s/test1/stest/longdirectory1/directory2/ --optnion12 --verbose
C dumper inf
Traceback (most recent call last):
File "/private/tmp/test-yaml.py", line 12, in <module>
print(yaml.dump([dict(ATTRIBUTES=[dict(CONFIG=x)])], width=float("inf"), Dumper=CDumper))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/simon/.local/lib/python3.12/site-packages/yaml/__init__.py", line 253, in dump
return dump_all([data], stream, Dumper=Dumper, **kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/simon/.local/lib/python3.12/site-packages/yaml/__init__.py", line 232, in dump_all
dumper = Dumper(stream, default_style=default_style,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/simon/.local/lib/python3.12/site-packages/yaml/cyaml.py", line 93, in __init__
CEmitter.__init__(self, stream, canonical=canonical,
File "yaml/_yaml.pyx", line 921, in yaml._yaml.CEmitter.__init__
OverflowError: cannot convert float infinity to integer
class CDumper(...):
def __init__(..., width=None, ...):
CEmitter.__init__(..., width=width, ...)
cdef class CEmitter:
...
def __init__(..., width=None, ...)
...
if width is not None:
yaml_emitter_set_width(..., width)
https://github.com/yaml/libyaml/blob/840b65c40675e2d06bf40405ad3f12dec7f35923/src/api.c#L548-L553
yaml_emitter_set_width(..., int width)
{
assert(emitter); /* Non-NULL emitter object expected. */
emitter->best_width = (width >= 0) ? width : -1;
}
if (emitter->best_width < 0) {
emitter->best_width = INT_MAX;
}
class Dumper(...):
def __init__(..., width=None, ...):
Emitter.__init__(..., width=width, ...)
class Emitter:
def __init__(..., width=None, ...):
...
self.best_width = 80
if width and width > self.best_indent*2:
self.best_width = width