我有以下YAML文件:
---
my_vars:
my_env: "dev"
my_count: 3
当我用PyYAML读取它并再次转储它时,我得到以下输出:
---
my_vars:
my_env: dev
my_count: 3
有问题的代码:
with open(env_file) as f:
env_dict = yaml.load(f)
print(yaml.dump(env_dict, indent=4, default_flow_style=False, explicit_start=True))
我尝试使用default_style
参数:
with open(env_file) as f:
env_dict = yaml.load(f)
print(yaml.dump(env_dict, indent=4, default_flow_style=False, explicit_start=True, default_style='"'))
但现在我得到:
---
"my_vars":
"my_env": "dev"
"my_count": !!int "3"
在不对YAML文件中的变量名做任何假设的情况下,我需要做什么来保持原始格式?
我建议您使用向后兼容的ruamel.yaml
软件包更新为使用YAML 1.2(2009年发布),而不是使用实现大部分YAML 1.1(2005)的PyYAML。 (免责声明:我是该套餐的作者)。
然后你只需在加载YAML文件的往返时指定preserve_quotes=True
:
import sys
import ruamel.yaml
yaml_str = """\
---
my_vars:
my_env: "dev" # keep "dev" quoted
my_count: 3
"""
data = ruamel.yaml.round_trip_load(yaml_str, preserve_quotes=True)
ruamel.yaml.round_trip_dump(data, sys.stdout, explicit_start=True)
哪些输出(包括保留的评论):
---
my_vars:
my_env: "dev" # keep "dev" quoted
my_count: 3
加载字符串后,标量将是字符串的子类,以便能够容纳引用信息,但是对于所有其他目的,它将像普通字符串一样工作。如果你想要替换这样的字符串(dev
到fgw
),你必须将字符串强制转换为这个子类(来自DoubleQuotedScalarString
的ruamel.yaml.scalarstring
)。
当默认往返ruamel.yaml
时,保留键的顺序(通过插入)。
是的,所以从this answer大量借用,你可以这样做:
import yaml
# define a custom representer for strings
def quoted_presenter(dumper, data):
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"')
yaml.add_representer(str, quoted_presenter)
env_file = 'input.txt'
with open(env_file) as f:
env_dict = yaml.load(f)
print yaml.dump(env_dict, default_flow_style=False)
但是,这只会在字典中的所有字符串类型上重载它,因此它也会引用键,而不仅仅是值。
它打印:
"my_vars":
"my_count": 3
"my_env": "dev"
这是你想要的吗?不确定你的变量名是什么意思,你的意思是键吗?