如何解决使用 yaml.dump 时如何去掉字符串中的引号
我正在尝试使用 ruamel.yaml 从有序字典中生成 cloudformation YAML 模板。
我需要在一些字符串前加上“!Sub
”,它是一个云模板函数引用,其方式不是用其他字符串用引号括起来,例如:
Type: AWS::glue::Job
Properties:
Role2: !Sub 'arn:aws:iam::${AWS::AccountId}:role/${glueServiceRole}'
我开始的测试代码如下所示:
from ruamel import yaml
from collections import OrderedDict
def ordered_dict_presenter(dumper,data):
return dumper.represent_dict(data.items())
test = OrderedDict(
{
"Type": "AWS::glue::Job","Properties": {
"Name": "test_job","Role": "!Sub arn:aws:iam::${AWS::AccountId}:role/${glueServiceRole}","Role2": "Sub arn:aws:iam::${AWS::AccountId}:role/${glueServiceRole}",},}
)
yaml.add_representer(OrderedDict,ordered_dict_presenter)
print(yaml.dump(test,default_style=None,default_flow_style=False))
它输出这个yaml:
Type: AWS::glue::Job
Properties:
Name: test_job
Role: '!Sub arn:aws:iam::${AWS::AccountId}:role/${glueServiceRole}'
Role2: Sub arn:aws:iam::${AWS::AccountId}:role/${glueServiceRole}
似乎当一个字符串以非字母字符开头时,它会被自动引用。 我尝试过自定义代表来摆脱引号,但到目前为止没有任何运气。我怎样才能输出这个?
解决方法
首先你真的不应该再使用旧的 API,有一个新的,它允许更多的控制 过去几年你在做什么。
其次,您不能在字符串中放入看起来像标签的东西
没有得到报价,在加载过程中会像标签一样加载,你可能想要
那,但这会产生无限数量的字符串(所有以
!
) 在 YAML 中不可表示。
如果您不知道从哪里开始,要做的就是尝试往返(加载然后转储)您需要的结果:
import sys
import ruamel.yaml
yaml_str = """\
Type: AWS::Glue::Job
Properties:
Role2: !Sub arn:aws:iam::${AWS::AccountId}:role/${GlueServiceRole}
"""
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
data = yaml.load(yaml_str)
yaml.dump(data,sys.stdout)
这给出:
Type: AWS::Glue::Job
Properties:
Role2: !Sub arn:aws:iam::${AWS::AccountId}:role/${GlueServiceRole}
这证实了 ruamel.yaml 可以创建输出。现在你只需要从头开始。您可以为哪些
检查 data
尤其是 data['Properties']['Role2']
(如果事情不经常但不必要地往返,意味着
你不能生成你想要的东西,但在这种情况下找出如何去做可能会更难)。
print(type(data['Properties']['Role2']))
打印:
Type: AWS::Glue::Job
Properties:
Role2: !Sub arn:aws:iam::${AWS::AccountId}:role/${GlueServiceRole}
<class 'ruamel.yaml.comments.TaggedScalar'>
现在您只需了解 TaggedScalar 的工作原理(源代码在 comments.py
中):
import sys
import ruamel.yaml
data = {}
data['Properties'] = props = {}
props['Role2'] = ruamel.yaml.comments.TaggedScalar('arn:aws:iam::${AWS::AccountId}:role/${GlueServiceRole}',style=None,tag='!Sub')
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.dump(data,sys.stdout)
给予:
Properties:
Role2: !Sub arn:aws:iam::${AWS::AccountId}:role/${GlueServiceRole}
或者,如果您确实想要引号,您可以指定 style="'"
或 style='"'
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。