Python 在不更改格式的情况下更新 YAML
Python update YAML without changing formatting
我想更新 yaml 文件中的特定 属性,同时保持其余部分不变,包括格式、评论等。我正在使用 raumel.yaml。但是当我保存文件时,它的格式被弄乱了。我正在使用 python 3.9.5 和 raumel.yaml 版本:0.17.10.
test.yaml
:
sso:
version: 1.0.0
configs:
- configName: config1.conf
fileContent: 'startDelaySeconds: 0
lowercaseOutputName: true
lowercaseOutputLabelNames: false
whitelistObjectNames: [''org.apache.commons.pool2:*'']
blacklistObjectNames: []
rules:
- pattern: ".*"
'
我将版本更新为:
from ruamel.yaml import YAML
yaml = YAML()
with open('test.yaml') as f:
test = yaml.load(f)
test['sso']['version'] = '1.0.1'
with open('test2.yaml', 'w') as f:
yaml.dump(test, f)
但是保存文件的 fileContent
格式发生了变化(换行符被 \n
等代替)。 test2.yaml
:
sso:
version: 1.0.1
configs:
- configName: config1.conf
fileContent: "startDelaySeconds: 0\nlowercaseOutputName: true\nlowercaseOutputLabelNames:\
\ false\nwhitelistObjectNames: ['org.apache.commons.pool2:*']\nblacklistObjectNames:\
\ []\nrules:\n- pattern: \".*\"\n"
您可能错过的是值中的引号
对于您的输出从单引号更改为双引号。默认 ruamel.yaml
不会尝试保留引号,从而能够删除任何多余的
引号,或者在这种情况下使用更紧凑的表示。
在标量中使用不需要单引号的双引号
被复制。
您可以通过设置 .preserve_quotes
属性来保留引号:
import sys
from ruamel.yaml import YAML
yaml = YAML()
yaml.preserve_quotes = True
with open('test.yaml') as f:
test = yaml.load(f)
test['sso']['version'] = '1.0.1'
yaml.dump(test, sys.stdout)
给出:
sso:
version: 1.0.1
configs:
- configName: config1.conf
fileContent: 'startDelaySeconds: 0
lowercaseOutputName: true
lowercaseOutputLabelNames: false
whitelistObjectNames: [''org.apache.commons.pool2:*'']
blacklistObjectNames: []
rules:
- pattern: ".*"
'
我建议考虑对值使用文字样式标量
包含换行符的,因为在那些你不需要加倍换行符的情况下,
也不需要在标量中加双单引号:
yaml_str = """
sso:
version: 1.0.0
configs:
- configName: config1.conf
fileContent: |
startDelaySeconds: 0
lowercaseOutputName: true
lowercaseOutputLabelNames: false
whitelistObjectNames: ['org.apache.commons.pool2:*']
blacklistObjectNames: []
rules:
- pattern: ".*"
"""
import sys
from ruamel.yaml import YAML
yaml = YAML()
yaml.preserve_quotes = True
with open('test.yaml') as f:
test = yaml.load(f)
data = yaml.load(yaml_str)
assert data['sso']['configs'][0]['fileContent'] == test['sso']['configs'][0]['fileContent']
我想更新 yaml 文件中的特定 属性,同时保持其余部分不变,包括格式、评论等。我正在使用 raumel.yaml。但是当我保存文件时,它的格式被弄乱了。我正在使用 python 3.9.5 和 raumel.yaml 版本:0.17.10.
test.yaml
:
sso:
version: 1.0.0
configs:
- configName: config1.conf
fileContent: 'startDelaySeconds: 0
lowercaseOutputName: true
lowercaseOutputLabelNames: false
whitelistObjectNames: [''org.apache.commons.pool2:*'']
blacklistObjectNames: []
rules:
- pattern: ".*"
'
我将版本更新为:
from ruamel.yaml import YAML
yaml = YAML()
with open('test.yaml') as f:
test = yaml.load(f)
test['sso']['version'] = '1.0.1'
with open('test2.yaml', 'w') as f:
yaml.dump(test, f)
但是保存文件的 fileContent
格式发生了变化(换行符被 \n
等代替)。 test2.yaml
:
sso:
version: 1.0.1
configs:
- configName: config1.conf
fileContent: "startDelaySeconds: 0\nlowercaseOutputName: true\nlowercaseOutputLabelNames:\
\ false\nwhitelistObjectNames: ['org.apache.commons.pool2:*']\nblacklistObjectNames:\
\ []\nrules:\n- pattern: \".*\"\n"
您可能错过的是值中的引号
对于您的输出从单引号更改为双引号。默认 ruamel.yaml
不会尝试保留引号,从而能够删除任何多余的
引号,或者在这种情况下使用更紧凑的表示。
在标量中使用不需要单引号的双引号
被复制。
您可以通过设置 .preserve_quotes
属性来保留引号:
import sys
from ruamel.yaml import YAML
yaml = YAML()
yaml.preserve_quotes = True
with open('test.yaml') as f:
test = yaml.load(f)
test['sso']['version'] = '1.0.1'
yaml.dump(test, sys.stdout)
给出:
sso:
version: 1.0.1
configs:
- configName: config1.conf
fileContent: 'startDelaySeconds: 0
lowercaseOutputName: true
lowercaseOutputLabelNames: false
whitelistObjectNames: [''org.apache.commons.pool2:*'']
blacklistObjectNames: []
rules:
- pattern: ".*"
'
我建议考虑对值使用文字样式标量 包含换行符的,因为在那些你不需要加倍换行符的情况下, 也不需要在标量中加双单引号:
yaml_str = """
sso:
version: 1.0.0
configs:
- configName: config1.conf
fileContent: |
startDelaySeconds: 0
lowercaseOutputName: true
lowercaseOutputLabelNames: false
whitelistObjectNames: ['org.apache.commons.pool2:*']
blacklistObjectNames: []
rules:
- pattern: ".*"
"""
import sys
from ruamel.yaml import YAML
yaml = YAML()
yaml.preserve_quotes = True
with open('test.yaml') as f:
test = yaml.load(f)
data = yaml.load(yaml_str)
assert data['sso']['configs'][0]['fileContent'] == test['sso']['configs'][0]['fileContent']