我环顾了几个小时,无所不包。这意味着我比我了解得多。
main:
user-settings:
accountID: 666
timestamp: 00:00
client settings:
nickname: "mainPC"
region: "OK"
例如,如何打印“帐户ID”和“区域”?
如果我想将accountID从666更改为102,该怎么办?
答案 0 :(得分:0)
您无法真正做到您在PyYAML中所要求的,甚至对于小型企业也是如此
你的例子。打印请求的值有效,但是当您更新时
您的YAML,您会看到它更改了
除了accountID
的值。假设您的YAML文件是
test.yaml
:
from pathlib import Path
import yaml
yaml_file = Path('test.yaml')
with yaml_file.open() as fp:
data = yaml.safe_load(fp)
user_settings = data['main']['user-settings']
print('acount id:', user_settings['accountID'])
user_settings['accountID'] = 102
print('region: ', data['main']['client settings']['region'])
with yaml_file.open('w') as fp:
yaml.safe_dump(data, fp, indent=4, default_flow_style=False)
此输出:
acount id: 666
region: OK
test.yaml
的内容将是:
main:
client settings:
nickname: mainPC
region: OK
user-settings:
accountID: 102
timestamp: 00:00
对于YAML文件中的任何映射,您都会得到一个Python dict
,并且
如果您的YAML中有序列,则使用Python list
。打印
所需的值,您只需遍历嵌套的dict
。
如您所见,您松开了OK
和mainPC
周围的引号,您
在00:00
附近吸引他们。后者是因为PyYAML尚未
更新以处理回传的最新YAML 1.2标准
2009。在YAML 1.1中,形式为XX:YY的标量被假定为
sexagesimals和
转换(并转储)为整数(如果有
小数点)。您的00:00
作为字符串加载是因为
前导零。如果它是12:00
,那么您的输出文件将
是timestamp: 720
。
映射中键的顺序也不是 保留。语义上这没有什么区别,但是如果此文件是 在版本控制下,这些更改很快就会变得令人困惑。
您应使用safe_load()
,因为“标准” load()
可能不安全
不受控制的YAML输入,尽管有文件记录,但大多数人没有
意识到这一点,也基本上没有必要。 (不安全为
或什至更糟。)
如果要更新YAML文件,建议使用
ruamel.yaml
(免责声明:我
是该软件包的作者。
from pathlib import Path
import ruamel.yaml
yaml_file = Path('test.yaml')
yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4)
yaml.preserve_quotes = True
data = yaml.load(yaml_file)
user_settings = data['main']['user-settings']
print('acount id:', user_settings['accountID'])
user_settings['accountID'] = 102
print('region: ', data['main']['client settings']['region'])
yaml.dump(data, yaml_file)
它还会输出:
acount id: 666
region: OK
test.yaml
的内容将是:
main:
user-settings:
accountID: 102
timestamp: 00:00
client settings:
nickname: "mainPC"
region: "OK"
不仅正确地保留了引号,而且不必
引用00:00
,因为ruamel.yaml
处理YAML 1.2,其中
六性动物完全掉下¹。映射中键的顺序
被保留。
如果在test.yaml
中有注释,那么PyYAML
将丢弃这些注释,
而ruamel.yaml
也保留这些内容。
在ruamel.yaml
中,默认的YAML()
使用安全的加载程序。
¹如果创建Sexagesimal
,您仍然可以使用六进制
分类并适当标记它们。在这种情况下,您也可以决定
具有前导零(!sexagesimal 00:00
),并正确转储这些值
返回为带标签的,未引用的标量。