我目前正在将此代码块与 pyyaml 一起使用,但我想用 ruamel.yaml 完成同样的事情
import yaml
import json
envList=envList={"env":"development", "region":"us", "tag":"latest", "kubesvcname":"service", "containername":"testcontainer", "namespace":"kubens", "buildid":"1000"}
jsonFile = json.dumps(envList, indent=4)
configMapHeader={ \
"apiVersion": "v1", \
"kind":"ConfigMap", \
"metadata": { \
"name": f'{envList["kubesvcname"]}_{envList["containername"]}-{envList["tag"]}-{envList["buildid"]}', \
"namespace": f'{envList["namespace"]}'\
},
"data":{"appsettings.json": \
jsonFile }
}
def str_presenter(dumper, data):
"""configures yaml for dumping multiline strings
Ref: https://stackoverflow.com/questions/8640959/how-can-i-control-what-scalar-form-pyyaml-uses-for-my-data"""
if len(data.splitlines()) > 1: # check for multiline string
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
return dumper.represent_scalar('tag:yaml.org,2002:str', data)
yaml.representer.SafeRepresenter.add_representer(str, str_presenter)
print(yaml.safe_dump(configMapHeader, sort_keys=False, line_break=True))
其输出看起来像这样:
apiVersion: v1
kind: ConfigMap
metadata:
name: service_testcontainer-latest-1000
namespace: kubens
data:
appsettings.json: |-
{
"env": "development",
"region": "us",
"tag": "latest",
"kubesvcname": "service",
"containername": "testcontainer",
"namespace": "kubens",
"buildid": "1000"
}
当我尝试用 ruamel.yaml 做类似的事情时,我得到了 输出文件中的换行符。
这是代码:
def initYamlParser():
import ruamel.yaml as yaml
yaml = yaml.YAML()
yaml.preserve_quotes = True
yaml.explicit_start = True
return yaml
import sys
import json
yaml=initYamlParser()
envList=envList={"env":"development", "region":"us", "tag":"latest", "kubesvcname":"service", "containerver": "latest", "containername":"testcontainer", "namespace":"kubens", "buildid":"1000"}
jsonFile = json.dumps(envList, indent=4)
configMapHeader={ \
"apiVersion": "v1", \
"kind":"ConfigMap", \
"metadata": { \
"name": f'{envList["kubesvcname"]}_{envList["containername"]}-{envList["containerver"]}-{envList["buildid"]}', \
"namespace": f'{envList["namespace"]}'\
},
"data":{"appsettings.json": \
jsonFile }
}
print(configMapHeader)
with open("file.yaml", 'w+') as file:
yaml.dump(configMapHeader, file)
这是输出:
apiVersion: v1
kind: ConfigMap
metadata:
name: service_testcontainer-latest-1000
namespace: kubens
data:
appsettings.json: "{\n \"env\": \"development\",\n \"region\": \"us\",\n \
\ \"tag\": \"latest\",\n \"kubesvcname\": \"service\",\n \"containerver\"\
: \"latest\",\n \"containername\": \"testcontainer\",\n \"namespace\": \"\
kubens\",\n \"buildid\": \"1000\"\n}"
Ruamel.yaml 不支持 str_presenter,所以我希望有一个该函数的 ruamel.yaml 兼容版本,或者一种使用 ruamel.yaml 在内部呈现它的方法
首先,转储 YAML 文档时通常不应附加到文件。自从
ruamel.yaml
将 UTF-8 写入文件,将其打开为 "wb"
。
您设置了
yaml.preserve_quotes = True
,但这仅在您往返时有效(加载 YAML,然后转储它)。
然后在
ruamel.yaml
中,您也可以拥有不同的表示者,只需将其附加到 representer
属性(这是
Representer
属性,默认为RoundTripRepresenter
)。唯一的区别是它传递一个代表作为第一个参数:
import sys
import json
import ruamel.yaml
yaml = ruamel.yaml.YAML()
yaml.explicit_start = True
def str_presenter(cls, data):
if len(data.splitlines()) > 1: # check for multiline string
return cls.represent_scalar('tag:yaml.org,2002:str', data, style='|')
return cls.represent_scalar('tag:yaml.org,2002:str', data)
yaml.representer.add_representer(str, str_presenter)
envList={"env":"development", "region":"us", "tag":"latest", "kubesvcname":"service", "containerver": "latest", "containername":"testcontainer", "namespace":"kubens", "buildid":"1000"}
jsonFile = json.dumps(envList, indent=4)
configMapHeader={ \
"apiVersion": "v1", \
"kind":"ConfigMap", \
"metadata": { \
"name": f'{envList["kubesvcname"]}_{envList["containername"]}-{envList["containerver"]}-{envList["buildid"]}', \
"namespace": f'{envList["namespace"]}'\
},
"data":{"appsettings.json": \
jsonFile }
}
# print(data)
yaml.dump(configMapHeader, sys.stdout)
给出:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: service_testcontainer-latest-1000
namespace: kubens
data:
appsettings.json: |-
{
"env": "development",
"region": "us",
"tag": "latest",
"kubesvcname": "service",
"containerver": "latest",
"containername": "testcontainer",
"namespace": "kubens",
"buildid": "1000"
}
如果您加载预期的输出然后转储它,您可以看到
ruamel.yaml
可以保留块样式文字标量。
通过检查键 appsetting.json
的值,您将看到这是 LiteralScalarString
类的实例。
该知识可用于仅以这种方式转储一个标量(而不是所有嵌入换行符的标量):
import sys
import json
import ruamel.yaml
yaml = ruamel.yaml.YAML()
yaml.explicit_start = True
envList={"env":"development", "region":"us", "tag":"latest", "kubesvcname":"service", "containerver": "latest", "containername":"testcontainer", "namespace":"kubens", "buildid":"1000"}
jsonFile = json.dumps(envList, indent=4)
configMapHeader={ \
"apiVersion": "v1", \
"kind":"ConfigMap", \
"metadata": { \
"name": f'{envList["kubesvcname"]}_{envList["containername"]}-{envList["containerver"]}-{envList["buildid"]}', \
"namespace": f'{envList["namespace"]}'\
},
"data":{"appsettings.json": \
ruamel.yaml.scalarstring.LiteralScalarString(jsonFile) }
}
yaml.dump(configMapHeader, sys.stdout)
给出:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: service_testcontainer-latest-1000
namespace: kubens
data:
appsettings.json: |-
{
"env": "development",
"region": "us",
"tag": "latest",
"kubesvcname": "service",
"containerver": "latest",
"containername": "testcontainer",
"namespace": "kubens",
"buildid": "1000"
}
envList=envList=....
,不知道为什么为同一个变量分配两次|-
,因为 JSON 转储器输出不包括
最后的换行符