Python YAML 转储特殊字符和多行
Python YAML dump special character and multiple lines
我有一个包含以下内容的 my_yaml.yml
文件:
my_yaml:
person: >
John|Doe|48,
Jack|Black|39
skills:
- name: superhero
abilities:
- swim
- run
special_chars:
- '! | " "'
- '+ | " "'
- '\ | " "'
- 'Á | "A"'
- 'É | "E"'
- 'Ű | "U"'
- 'Û | "U"'
我想加载它然后转储到一个 my_yaml_new.yml
文件中,该文件具有与原始输入文件完全相同的格式和字符。我的代码是:
import yaml
my_yaml = yaml.load(open('my_yaml.yml', encoding='utf8')) # without "utf8" encoding I get "'charmap' codec can't decode byte..." error
我可以 dump
它进入控制台,但是 1) abilities
& name
的顺序已经改变了:(
yaml.dump(my_yaml, default_flow_style=False, allow_unicode=True)
结果是:
'my_yaml:\n person: >\n John|Doe|48, Jack|Black|39\n skills:\n - abilities:\n - swim\n - run\n name: superhero\n special_chars:\n - \'! | " "\'\n - + | " "\n - \ | " "\n - Á | "A"\n - É | "E"\n - Ű | "U"\n - Û | "U"\n'
当我尝试转储到文件中时:
with open('my_yaml_new.yml', 'w') as outfile:
yaml.dump(my_yaml, outfile, default_flow_style=False, allow_unicode=True)
2) 由于字符 Û
:
我收到以下错误
UnicodeEncodeError: 'charmap' codec can't encode character '\xdb' in
position 0: character maps to undefined
如果我从输入 my_yaml.yml
文件中删除这一行,那么上面的转储是成功的,但是 3) 我在 person
字符串中的多行进入一行 :(
my_yaml:
person: >
John|Doe|48, Jack|Black|39
skills:
- abilities:
- swim
- run
name: superhero
special_chars:
- '! | " "'
- + | " "
- \ | " "
- Á | "A"
- É | "E"
- Ű | "U"
4) 而且我的单引号 (') 从 special_chars
中消失了:(
5) 还要注意 skills
的元素没有缩进 :(
我已经尝试 these 解决方案但没有成功。 import ruamel.yaml as yaml
也没有帮助。
更新
OK,下面这个大包解决了问题1) & 4),我可以把>
换成|
为多行值,因此 3) 也已解决。也许 5) 不是一个大问题。但我仍然在与 Û
或 Ǘ
等特殊字符作斗争,所以我仍在寻找问题 2)...
的解决方案
from ruamel import yaml
my_yaml = yaml.round_trip_load(open('dmy_yaml.yml', encoding='utf8'), preserve_quotes=True)
with open('my_yaml_new.yml', 'w') as outfile:
yaml.round_trip_dump(my_yaml, outfile, default_flow_style=False, allow_unicode=True)
我不确定您为什么遇到 unicode 问题。如果您有 my_yaml.yml
和程序 try.py
:
import sys
import ruamel.yaml
with open('my_yaml.yml') as fp:
yaml_str = fp.read().replace(': >\n', ': |\n')
yaml = ruamel.yaml.YAML()
yaml.indent(mapping=2, sequence=4, offset=2)
yaml.preserve_quotes = True
data = yaml.load(yaml_str)
new_file = 'my_yaml_new.yml'
with open(new_file, 'w') as ofp:
yaml.dump(data, ofp)
然后生成:
my_yaml:
person: |
John|Doe|48,
Jack|Black|39
skills:
- name: superhero
abilities:
- swim
- run
special_chars:
- '! | " "'
- '+ | " "'
- '\ | " "'
- 'Á | "A"'
- 'É | "E"'
- 'Ű | "U"'
- 'Û | "U"'
在 Python2 和 Python3 的 virtualenv 中 ruamel.yaml 0.15.40.
我用过:
for n in 2 3 ; do mktmpenv -p /opt/python/$n/bin/python -qq -i ruamel.yaml; python --version; python try.py; deactivate; done
这当然依赖于 Python 2 和 3 的(最新)版本安装在 /opt/python/2
下。 /opt/python/3
(它们在我的 Linux 开发系统上)。
请注意,Unicode 显示没有问题,yaml.indent(mapping=2, sequence=4, offset=2)
保留了您的源缩进,但您仍然需要将折叠的多行标量更改为文字样式(我在阅读 yaml_str
) 因为 ruamel.yaml 不支持保留它(主要是因为没有简单的方法以透明的方式指示原始折叠点)。
我有一个包含以下内容的 my_yaml.yml
文件:
my_yaml:
person: >
John|Doe|48,
Jack|Black|39
skills:
- name: superhero
abilities:
- swim
- run
special_chars:
- '! | " "'
- '+ | " "'
- '\ | " "'
- 'Á | "A"'
- 'É | "E"'
- 'Ű | "U"'
- 'Û | "U"'
我想加载它然后转储到一个 my_yaml_new.yml
文件中,该文件具有与原始输入文件完全相同的格式和字符。我的代码是:
import yaml
my_yaml = yaml.load(open('my_yaml.yml', encoding='utf8')) # without "utf8" encoding I get "'charmap' codec can't decode byte..." error
我可以 dump
它进入控制台,但是 1) abilities
& name
的顺序已经改变了:(
yaml.dump(my_yaml, default_flow_style=False, allow_unicode=True)
结果是:
'my_yaml:\n person: >\n John|Doe|48, Jack|Black|39\n skills:\n - abilities:\n - swim\n - run\n name: superhero\n special_chars:\n - \'! | " "\'\n - + | " "\n - \ | " "\n - Á | "A"\n - É | "E"\n - Ű | "U"\n - Û | "U"\n'
当我尝试转储到文件中时:
with open('my_yaml_new.yml', 'w') as outfile:
yaml.dump(my_yaml, outfile, default_flow_style=False, allow_unicode=True)
2) 由于字符 Û
:
UnicodeEncodeError: 'charmap' codec can't encode character '\xdb' in position 0: character maps to undefined
如果我从输入 my_yaml.yml
文件中删除这一行,那么上面的转储是成功的,但是 3) 我在 person
字符串中的多行进入一行 :(
my_yaml:
person: >
John|Doe|48, Jack|Black|39
skills:
- abilities:
- swim
- run
name: superhero
special_chars:
- '! | " "'
- + | " "
- \ | " "
- Á | "A"
- É | "E"
- Ű | "U"
4) 而且我的单引号 (') 从 special_chars
中消失了:(
5) 还要注意 skills
的元素没有缩进 :(
我已经尝试 these 解决方案但没有成功。 import ruamel.yaml as yaml
也没有帮助。
更新
OK,下面这个大包解决了问题1) & 4),我可以把>
换成|
为多行值,因此 3) 也已解决。也许 5) 不是一个大问题。但我仍然在与 Û
或 Ǘ
等特殊字符作斗争,所以我仍在寻找问题 2)...
from ruamel import yaml
my_yaml = yaml.round_trip_load(open('dmy_yaml.yml', encoding='utf8'), preserve_quotes=True)
with open('my_yaml_new.yml', 'w') as outfile:
yaml.round_trip_dump(my_yaml, outfile, default_flow_style=False, allow_unicode=True)
我不确定您为什么遇到 unicode 问题。如果您有 my_yaml.yml
和程序 try.py
:
import sys
import ruamel.yaml
with open('my_yaml.yml') as fp:
yaml_str = fp.read().replace(': >\n', ': |\n')
yaml = ruamel.yaml.YAML()
yaml.indent(mapping=2, sequence=4, offset=2)
yaml.preserve_quotes = True
data = yaml.load(yaml_str)
new_file = 'my_yaml_new.yml'
with open(new_file, 'w') as ofp:
yaml.dump(data, ofp)
然后生成:
my_yaml:
person: |
John|Doe|48,
Jack|Black|39
skills:
- name: superhero
abilities:
- swim
- run
special_chars:
- '! | " "'
- '+ | " "'
- '\ | " "'
- 'Á | "A"'
- 'É | "E"'
- 'Ű | "U"'
- 'Û | "U"'
在 Python2 和 Python3 的 virtualenv 中 ruamel.yaml 0.15.40.
我用过:
for n in 2 3 ; do mktmpenv -p /opt/python/$n/bin/python -qq -i ruamel.yaml; python --version; python try.py; deactivate; done
这当然依赖于 Python 2 和 3 的(最新)版本安装在 /opt/python/2
下。 /opt/python/3
(它们在我的 Linux 开发系统上)。
请注意,Unicode 显示没有问题,yaml.indent(mapping=2, sequence=4, offset=2)
保留了您的源缩进,但您仍然需要将折叠的多行标量更改为文字样式(我在阅读 yaml_str
) 因为 ruamel.yaml 不支持保留它(主要是因为没有简单的方法以透明的方式指示原始折叠点)。