Python ruamel.yaml - 在将 yaml 转换为 dict 并将结果保存到 yaml 文件时保留值中的引号
Python ruamel.yaml - preserving quote in value while convert yaml to dict and save result to yaml file
我正在尝试将 YAML 文件加载到字典,然后将字典和安全 YAML 流处理到文件,但遇到以下问题。
源 y.yaml 文件包含一些带双引号的字符串:
---
lev1:
lev2:
- name: schema
templates:
- name: temp1
deploy_onpr: "yes"
deploy_cl: "no"
我在 dest.yaml 中得到了什么:
---
lev1:
lev2:
- name: schema
new_item: test
templates:
- deploy_cl: no
deploy_onpr: yes
name: temp1
我们可以看到引号已从 yes 和 no 字符串中删除。
我在 dest.yaml 中期望的是不应从字符串中删除双引号:
---
lev1:
lev2:
- name: schema
new_item: test
templates:
- deploy_cl: "no"
deploy_onpr: "yes"
name: temp1
代码:
from fnmatch import fnmatch
import json
import os
from json import loads, dumps
import ruamel.yaml
yaml = ruamel.yaml.YAML(typ='safe', pure=True)
yaml.preserve_quotes = True
yaml.explicit_start = True
yaml.default_flow_style = False
yaml.indent(mapping=2, sequence=4, offset=2)
def to_dict(input_ordered_dict):
"""Convert the inventory data stream to dict"""
print(dumps(input_ordered_dict))
return loads(dumps(input_ordered_dict))
def _list_files():
'''
list all yaml files in the yaml directory recursive
'''
pattern = "*.yaml"
in_folder="./"
all_files = []
for path, subdirs, files in os.walk(in_folder):
for name in files:
if fnmatch(name, pattern):
f = os.path.join(path, name)
all_files.append(f)
return all_files
def load_files():
'''
load directory recursive and generate a dict tree
data allocated in the structure under the key "file name"
'''
dict_tree = {}
for sfile in _list_files():
with open(sfile, 'r') as stream:
print(type(yaml))
data_loaded = yaml.load(stream)
print(data_loaded)
dict_tree[sfile] = data_loaded
return dict_tree
load_yaml_files = load_files()
inventoty_data = to_dict(load_yaml_files)
inventoty_data['./y.yaml']["lev1"]["lev2"][0]["new_item"]="test"
new_dict=inventoty_data["./y.yaml"]
dst_file="dest.yaml"
with open(dst_file, 'w') as yaml_file:
yaml.dump(new_dict, yaml_file)
这看起来像 YAML 1.1,其中 yes
和 no
应该是布尔值(因此
如果它们是标量字符串,则需要引用)。
preserve_quotes
属性仅在使用默认 round-trip 加载程序和转储程序时有效
(使用 SafeLoader
的子类,也可以安全地用于未知的 YAML 源):
import sys
import ruamel.yaml
from pathlib import Path
yaml = ruamel.yaml.YAML()
yaml.explicit_start = True
yaml.indent(sequence=4, offset=2)
yaml.preserve_quotes = True
data = yaml.load(Path('y.yaml'))
yaml.dump(data, sys.stdout)
给出:
---
lev1:
lev2:
- name: schema
templates:
- name: temp1
deploy_onpr: "yes"
deploy_cl: "no"
即使您将 data
作为值分配给普通字典中的键,
加载期间创建的字符串的特殊版本将被保留并用引号转储。
如果您需要 add/update Python 中的某些值需要字符串 "abc"
的引号,那么请执行:
DQ = ruamel.yaml.scalarstring.DoubleQuotesScalarString
some_place_in_your_data_structure = DQ("abc")`
以下代码按预期工作:
from fnmatch import fnmatch
import json
import os
from json import loads, dumps
import ruamel.yaml
import sys
import ruamel.yaml
from pathlib import Path
ruamel.yaml.representer.RoundTripRepresenter.ignore_aliases = lambda x, y: True
yaml = ruamel.yaml.YAML()
yaml.explicit_start = True
yaml.indent(sequence=4, offset=2)
yaml.preserve_quotes = True
def _list_files():
'''
list all yaml files in the yaml directory recursive
'''
pattern = "*.yaml"
in_folder="./"
all_files = []
for path, subdirs, files in os.walk(in_folder):
for name in files:
if fnmatch(name, pattern):
f = os.path.join(path, name)
all_files.append(f)
return all_files
def load_files():
'''
load directory recursive and generate a dict tree
data allocated in the structure under the key "file name"
'''
dict_tree = {}
for sfile in _list_files():
with open(sfile, 'r') as stream:
data_loaded = yaml.load(stream)
print(data_loaded)
dict_tree[sfile] = data_loaded
return dict_tree
load_yaml_files = load_files()
inventoty_data = load_yaml_files
inventoty_data['./y.yaml']["lev1"]["lev2"][0]["new_item"]="test"
new_dict=inventoty_data["./y.yaml"]
dst_file="dest.yaml"
with open(dst_file, 'w') as yaml_file:
yaml.dump(new_dict, yaml_file)
输出:
---
lev1:
lev2:
- name: schema
templates:
- name: temp1
deploy_onpr: "yes"
deploy_cl: "no"
new_item: test
我正在尝试将 YAML 文件加载到字典,然后将字典和安全 YAML 流处理到文件,但遇到以下问题。
源 y.yaml 文件包含一些带双引号的字符串:
---
lev1:
lev2:
- name: schema
templates:
- name: temp1
deploy_onpr: "yes"
deploy_cl: "no"
我在 dest.yaml 中得到了什么:
---
lev1:
lev2:
- name: schema
new_item: test
templates:
- deploy_cl: no
deploy_onpr: yes
name: temp1
我们可以看到引号已从 yes 和 no 字符串中删除。
我在 dest.yaml 中期望的是不应从字符串中删除双引号:
---
lev1:
lev2:
- name: schema
new_item: test
templates:
- deploy_cl: "no"
deploy_onpr: "yes"
name: temp1
代码:
from fnmatch import fnmatch
import json
import os
from json import loads, dumps
import ruamel.yaml
yaml = ruamel.yaml.YAML(typ='safe', pure=True)
yaml.preserve_quotes = True
yaml.explicit_start = True
yaml.default_flow_style = False
yaml.indent(mapping=2, sequence=4, offset=2)
def to_dict(input_ordered_dict):
"""Convert the inventory data stream to dict"""
print(dumps(input_ordered_dict))
return loads(dumps(input_ordered_dict))
def _list_files():
'''
list all yaml files in the yaml directory recursive
'''
pattern = "*.yaml"
in_folder="./"
all_files = []
for path, subdirs, files in os.walk(in_folder):
for name in files:
if fnmatch(name, pattern):
f = os.path.join(path, name)
all_files.append(f)
return all_files
def load_files():
'''
load directory recursive and generate a dict tree
data allocated in the structure under the key "file name"
'''
dict_tree = {}
for sfile in _list_files():
with open(sfile, 'r') as stream:
print(type(yaml))
data_loaded = yaml.load(stream)
print(data_loaded)
dict_tree[sfile] = data_loaded
return dict_tree
load_yaml_files = load_files()
inventoty_data = to_dict(load_yaml_files)
inventoty_data['./y.yaml']["lev1"]["lev2"][0]["new_item"]="test"
new_dict=inventoty_data["./y.yaml"]
dst_file="dest.yaml"
with open(dst_file, 'w') as yaml_file:
yaml.dump(new_dict, yaml_file)
这看起来像 YAML 1.1,其中 yes
和 no
应该是布尔值(因此
如果它们是标量字符串,则需要引用)。
preserve_quotes
属性仅在使用默认 round-trip 加载程序和转储程序时有效
(使用 SafeLoader
的子类,也可以安全地用于未知的 YAML 源):
import sys
import ruamel.yaml
from pathlib import Path
yaml = ruamel.yaml.YAML()
yaml.explicit_start = True
yaml.indent(sequence=4, offset=2)
yaml.preserve_quotes = True
data = yaml.load(Path('y.yaml'))
yaml.dump(data, sys.stdout)
给出:
---
lev1:
lev2:
- name: schema
templates:
- name: temp1
deploy_onpr: "yes"
deploy_cl: "no"
即使您将 data
作为值分配给普通字典中的键,
加载期间创建的字符串的特殊版本将被保留并用引号转储。
如果您需要 add/update Python 中的某些值需要字符串 "abc"
的引号,那么请执行:
DQ = ruamel.yaml.scalarstring.DoubleQuotesScalarString
some_place_in_your_data_structure = DQ("abc")`
以下代码按预期工作:
from fnmatch import fnmatch
import json
import os
from json import loads, dumps
import ruamel.yaml
import sys
import ruamel.yaml
from pathlib import Path
ruamel.yaml.representer.RoundTripRepresenter.ignore_aliases = lambda x, y: True
yaml = ruamel.yaml.YAML()
yaml.explicit_start = True
yaml.indent(sequence=4, offset=2)
yaml.preserve_quotes = True
def _list_files():
'''
list all yaml files in the yaml directory recursive
'''
pattern = "*.yaml"
in_folder="./"
all_files = []
for path, subdirs, files in os.walk(in_folder):
for name in files:
if fnmatch(name, pattern):
f = os.path.join(path, name)
all_files.append(f)
return all_files
def load_files():
'''
load directory recursive and generate a dict tree
data allocated in the structure under the key "file name"
'''
dict_tree = {}
for sfile in _list_files():
with open(sfile, 'r') as stream:
data_loaded = yaml.load(stream)
print(data_loaded)
dict_tree[sfile] = data_loaded
return dict_tree
load_yaml_files = load_files()
inventoty_data = load_yaml_files
inventoty_data['./y.yaml']["lev1"]["lev2"][0]["new_item"]="test"
new_dict=inventoty_data["./y.yaml"]
dst_file="dest.yaml"
with open(dst_file, 'w') as yaml_file:
yaml.dump(new_dict, yaml_file)
输出:
---
lev1:
lev2:
- name: schema
templates:
- name: temp1
deploy_onpr: "yes"
deploy_cl: "no"
new_item: test