2016-01-05 21 views
5

Farklı ortamlar için dosyaları yapılandırmak üzere PyYAML kullanıyoruz. Ancak YAML bloklarımız bütünlüğünü kaybeder.Ayrıştırılmış bir belgeyi dökerken YAML blok yapısını korumak mümkün mü?

ver

pubkey: | 
    -----BEGIN PUBLIC KEY----- 
    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq 
    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2 
    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK 
    EsUgJHXcpw7OPxRrCQIDAQAB 
    -----END PUBLIC KEY----- 

... python3 kullanarak bu programı yürütme ...

import yaml 

with open('input.yml', mode='r') as f: 
    parsed = yaml.safe_load(f) 

with open('output.yml', mode='w') as f: 
    yaml.dump(parsed, f) 

... üretir input.yml ... Bu output.yml ...

pubkey: '-----BEGIN PUBLIC KEY----- 

    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq 

    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2 

    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK 

    EsUgJHXcpw7OPxRrCQIDAQAB 

    -----END PUBLIC KEY----- 

    ' 

Bloğumun yapısını PyYAML kullanarak korumak mümkün mü?

cevap

5

Evet o pyyaml ile mümkündür, ancak safe_load tarafından kullanılan en az Tarayıcı, Ayrıştırıcı ve Oluşturucu kendi geliştirilmiş sürümleri sağlamak zorunda, Emitör, seri hale ve DANIŞMANI dökümü, tarafından ve sağlayarak kullanılan Özgün biçimlendirme hakkında bilgi tutan özel bir string benzeri sınıf.

Bu ruamel.yaml eklendi şeyin parçasıdır (reddi: O paketin yazarıyım) o PyYAML türetilen ve yine benzer bir kurulum tutar gibi. ruamel.yaml kullanma:

import ruamel.yaml as yaml 

yaml_str = """\ 
pubkey: | 
    -----BEGIN PUBLIC KEY----- 
    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq 
    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2 
    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK 
    EsUgJHXcpw7OPxRrCQIDAQAB 
    -----END PUBLIC KEY----- 
""" 

data = yaml.load(yaml_str, Loader=yaml.RoundTripLoader) 
print(yaml.dump(data, Dumper=yaml.RoundTripDumper, indent=4)) 

verir:

pubkey: | 
    -----BEGIN PUBLIC KEY----- 
    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq 
    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2 
    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK 
    EsUgJHXcpw7OPxRrCQIDAQAB 
    -----END PUBLIC KEY----- 

en az Python 2.7 ve 3.5 ile. İki boşluklarına RoundTripDumper varsayılan girinti ve bir dosya korunmaz orijinal girinti olarak

indent=4 (yapmadığı yani YAML dosyasını yeniden girinti kolaylaştırır) gereklidir.

ruamel.yaml'a geçiş yapamıyorsanız, gereken tüm değişiklikleri ayıklamak için kaynağını kullanabilmeniz gerekir; ancak isterseniz, yorum ve anahtar adı koruma özelliğini kullanma gibi diğer özelliklerini de kullanabilirsiniz.

+0

Aferin. Ekstra yeni satırın eklendiği yeri anlamaya çalışırken pyyaml ​​kaynağından dolaşıyordum, bu yüzden umarım alt sınıfta kalacağım, ama yatmadan önce şans yoktu. – MattDMo

+0

@MattDMo "Normal" damperin içindeki ekstra satır, dizenin yeni satırlar içerdiğinden. Dizeleri özel karakterler ve PyYAML seçimleriyle temsil etmenin birçok yolu vardır. Seçim, scalar'ın analizine dayanan emitter.choose_scaler_style() dosyasındadır, ancak gerçekte nasıl çalıştığını izlemek gerçekten zordur. Bunları okurken özel bir yazı yazarak ve düğüm stilini açıkça belirleyerek atlatıyorum. – Anthon

+0

Sadece 'ruamel.yaml' kurdum ve onunla biraz oynuyorum: çok güzel. İki hızlı (konu dışı) soru: ad nereden geldi ve YAML 1.2'yi destekleme planlarınız var mı? Soruyorum çünkü çalışmak istediğim bazı dosyalar var: '% YAML 1.2' ilk satırı var. Spesifikasyonlar arasındaki farkların (1.2 spesifikasyonun 1. bölümünü okuduktan sonra bile) ya da dosyaların 1.2'deki herhangi bir yeni özellikten yararlanıp yararlanmadığı konusunda hiçbir fikrim yok. Bunlar temel olarak string veya boole değerleri olan metin tuşlarıdır. (nesne yok). İşte github bir: http://bit.ly/1JXLVbf – MattDMo