2016-07-14 47 views
4

我有以下YAML文件:pyyaml和使用字符串報價僅

--- 
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文件中的變量名的任何假設?

+0

爲什麼不直接打印該文件,使用字典作爲打印內容的來源而不是文件本身很重要? – Nobilis

+0

我將來會在字典中添加其他鍵,但佈局需要保留。 –

回答

1

對,所以從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" 

這是你想要的嗎?不知道你的變量名是什麼意思,你的意思是鑰匙?

+0

這已經幫助了我很多,謝謝:-)仍然不知道如何才能將它應用於值,而不是鍵。 –

+0

如果你有很多空閒時間,那麼我建議去yaml的[文檔](http:// pyyaml。org/wiki/PyYAMLDocumentation#Constructorsrepresentersresolvers)關於如何創建表示者,然後徹底閱讀YAML的標籤[here](http://www.yaml.org/spec/1.2/spec.html)。還有[這個答案](http://stackoverflow.com/questions/20805418/pyyaml-dump-format)討論了PyYaml的一個分支,它提到了一些關於保持原始格式的內容,可能也會有所幫助。 – Nobilis

3

我建議你更新使用YAML 1.2(2009年發佈)和向後兼容的ruamel.yaml包,而不是使用實現YAML 1.1(2005)大部分的PyYAML。 (免責聲明:我是該軟件包的作者)。

然後你只需加載的時候指定preserve_quotes=True往返的YAML文件:

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 

加載串標量將是一個後字符串的子類,以便能夠容納引用信息,但是對於所有其他用途,它將像普通字符串一樣工作。如果要替換這樣的字符串(devfgw) ,則必須將該字符串投射到此子類(DoubleQuotedScalarStringruamel.yaml.scalarstring)。

默認情況下,往返ruamel.yaml保留鍵(通過插入)的順序。