मैं पायथन में एक YAML फ़ाइल को पार्स कैसे कर सकता हूं


जवाबों:


804

सी हेडर पर भरोसा किए बिना सबसे आसान और शुद्धतम तरीका है PyYaml ( प्रलेखन ), जिसे इसके माध्यम से स्थापित किया जा सकता है pip install pyyaml:

#!/usr/bin/env python

import yaml

with open("example.yaml", 'r') as stream:
    try:
        print(yaml.safe_load(stream))
    except yaml.YAMLError as exc:
        print(exc)

और बस। एक सादा yaml.load()कार्य भी मौजूद है, लेकिन yaml.safe_load()हमेशा तब तक प्राथमिकता दी जानी चाहिए जब तक कि आपको स्पष्ट रूप से मनमाने ढंग से वस्तु क्रमबद्धता / डीरियलाइजेशन की आवश्यकता न हो, ताकि मनमाने कोड निष्पादन की संभावना से बचने के लिए प्रदान किया जा सके।

ध्यान दें कि PyYaml परियोजना YAML 1.1 विनिर्देशन के माध्यम से संस्करणों का समर्थन करती है । यदि YAML 1.2 विनिर्देश समर्थन की आवश्यकता है, तो इस उत्तर में नोट किए गए अनुसार ruamel.yaml देखें ।


96
मुझे लगता है कि जब तक आप मनमाने ढंग से वस्तुओं को क्रमांकित / निष्क्रिय करने की इच्छा नहीं रखते हैं, तब तक इसका उपयोग करना बेहतर होता है yaml.safe_loadक्योंकि यह YAML फ़ाइल से मनमाना कोड निष्पादित नहीं कर सकता है।
ternaryOperator

4
यमल यमल = नया यमल (); ऑब्जेक्ट obj = yaml.load ("a: 1 \ nb: 2 \ nc: \ n - aaa \ n - bbb");
MayTheSchwartzBeWith You

2
मुझे यह लेख पसंद आया
सौरभ

4
आपको पहले PyYAML पैकेज स्थापित करने की आवश्यकता हो सकती है pip install pyyaml, इस पोस्ट को अधिक विकल्पों के लिए देखें stackoverflow.com/questions/14261614/…
Romain

7
इस उदाहरण में अपवाद को पकड़ने की बात क्या है? यह वैसे भी मुद्रित करने जा रहा है, और यह सिर्फ उदाहरण को और अधिक जटिल बनाता है ..
n

115

पायथन 2 + 3 (और यूनिकोड) के साथ YAML फाइलें पढ़ें और लिखें

# -*- coding: utf-8 -*-
import yaml
import io

# Define data
data = {
    'a list': [
        1, 
        42, 
        3.141, 
        1337, 
        'help', 
        u'€'
    ],
    'a string': 'bla',
    'another dict': {
        'foo': 'bar',
        'key': 'value',
        'the answer': 42
    }
}

# Write YAML file
with io.open('data.yaml', 'w', encoding='utf8') as outfile:
    yaml.dump(data, outfile, default_flow_style=False, allow_unicode=True)

# Read YAML file
with open("data.yaml", 'r') as stream:
    data_loaded = yaml.safe_load(stream)

print(data == data_loaded)

YAML फ़ाइल बनाई गई

a list:
- 1
- 42
- 3.141
- 1337
- help
- 
a string: bla
another dict:
  foo: bar
  key: value
  the answer: 42

आम फ़ाइल अंत

.yml तथा .yaml

वैकल्पिक

आपके आवेदन के लिए, निम्नलिखित महत्वपूर्ण हो सकता है:

  • अन्य प्रोग्रामिंग भाषाओं द्वारा सहायता
  • पठन / लेखन प्रदर्शन
  • कॉम्पैक्टनेस (फ़ाइल आकार)

यह भी देखें: डेटा क्रमांकन प्रारूपों की तुलना

यदि आप विन्यास फाइल बनाने के लिए रास्ता ढूंढ रहे हैं, तो आप पायथन में मेरी संक्षिप्त लेख विन्यास फाइल पढ़ना चाहते हैं


विंडोज पर मेरा आउटपुट है €। किसी को कारण पता है?
क्लाउड चो

फ़ाइल में क्या एन्कोडिंग है? तुम्हें यकीन है कि यह utf-8 एन्कोडेड है?
मार्टिन थोमा

1
सुझाव के लिए धन्यवाद। मेरी फ़ाइल में utf-8 एन्कोडिंग है। io.open(doc_name, 'r', encoding='utf8')विशेष वर्ण पढ़ने के लिए मुझे आपकी कोड लाइन बदलनी होगी । YAML संस्करण 0.1.7
क्लाउड चो

हुह, दिलचस्प है। मैं उस कल को पुन: पेश करने की कोशिश करूंगा और यदि मैं कर सकता हूं तो सवाल को समायोजित करूंगा। धन्यवाद!
मार्टिन थॉमा

1
आप open(doc_name, ..., encodung='utf8')बिना आयात किए, पढ़ने और लिखने के लिए बिल्ट-इन का उपयोग कर सकते हैं io
dexteritas

61

यदि आपके पास YAML है जो YAML 1.2 विनिर्देश (2009 में जारी) के अनुरूप है, तो आपको ruamel.yaml (अस्वीकरण का उपयोग करना चाहिए : मैं उस पैकेज का लेखक हूं)। यह मूल रूप से PyYAML का सुपरसेट है, जो कि YAML 1.1 (2005 से) का अधिकांश समर्थन करता है।

यदि आप राउंड-ट्रिपिंग के दौरान अपनी टिप्पणियों को संरक्षित करने में सक्षम होना चाहते हैं, तो आपको निश्चित रूप से ruamel.yaml का उपयोग करना चाहिए।

उन्नयन @ जॉन का उदाहरण आसान है:

import ruamel.yaml as yaml

with open("example.yaml") as stream:
    try:
        print(yaml.safe_load(stream))
    except yaml.YAMLError as exc:
        print(exc)

safe_load()जब तक आप वास्तव में इनपुट पर पूर्ण नियंत्रण नहीं रखते, तब तक इसका उपयोग करें (शायद ही कभी मामला हो) और यह जानें कि आप क्या कर रहे हैं।

यदि आप Pathफ़ाइलों में हेरफेर करने के लिए पैथलिब का उपयोग कर रहे हैं , तो आप नए API रुमेलम का उपयोग कर रहे हैं।

from ruamel.yaml import YAML
from pathlib import Path

path = Path('example.yaml')
yaml = YAML(typ='safe')
data = yaml.load(path)

हैलो @Anthon। मैं रूबल का उपयोग कर रहा था, लेकिन उन दस्तावेज़ों के साथ एक मुद्दा मिला, जो एससीआई अनुपालन नहीं हैं ( UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 926: ordinal not in range(128))। मैं utf-8 के लिए yaml.encoding सेट करने की कोशिश की है, लेकिन YAML में लोड विधि के रूप में अभी भी काम नहीं किया ascii_decode का उपयोग करता है। क्या यह एक बग है?
SnwBr

27

पहले pip3 का उपयोग करके pyyaml ​​स्थापित करें।

फिर yaml मॉड्यूल आयात करें और फ़ाइल को 'my_dict' नामक शब्दकोश में लोड करें:

import yaml
with open('filename.yaml') as f:
    my_dict = yaml.safe_load(f)

बस इतना ही चाहिए। अब पूरी yaml फ़ाइल 'my_dict' डिक्शनरी में है।


6
क्या यह फ़ाइल को बंद करता है?
यांगमिल्सथोरी

2
यदि आपकी फ़ाइल में लाइन "- हैलो वर्ल्ड" है, तो चर my_dict को कॉल करना अनुचित है, क्योंकि इसमें एक सूची शामिल होने वाली है। यदि उस फ़ाइल में विशिष्ट टैग होते हैं (जिसके साथ शुरू होता है !!python) तो इसका उपयोग करने के लिए असुरक्षित (पूर्ण हार्डडिस्क मिटाए गए स्वच्छ) भी हो सकता है yaml.load()। जैसा कि स्पष्ट रूप से प्रलेखित है कि आपको यहां पर चेतावनी को दोहराया जाना चाहिए (लगभग सभी मामलों में yaml.safe_load()इसका इस्तेमाल किया जा सकता है)।
एंथन

4
आप उपयोग करते हैं import yaml, लेकिन यह बिल्ट-इन मॉड्यूल नहीं है, और आप यह निर्दिष्ट नहीं करते हैं कि यह कौन सा पैकेज है। import yamlताज़े पायथन 3 पर चलने से परिणाम सामने आते हैंModuleNotFoundError: No module named 'yaml'
काउलविनेटर

11

उदाहरण:


defaults.yaml

url: https://www.google.com

environment.py

from ruamel import yaml

data = yaml.safe_load(open('defaults.yaml'))
data['url']

क्या यह धारा को बंद नहीं करने के लिए बचा है?
qrtLs

3

मैं ruamel.yaml का उपयोग करता हूंविवरण और बहस यहाँ

from ruamel import yaml

with open(filename, 'r') as fp:
    read_data = yaml.load(fp)

PyamelAM के पुराने उपयोगों के साथ ruamel.yaml का उपयोग (कुछ सरल हल करने योग्य समस्याओं के साथ) संगत है और जैसा कि मैंने लिंक में बताया है, उपयोग

from ruamel import yaml

के बजाय

import yaml

और यह आपकी अधिकांश समस्याओं को ठीक कर देगा।

संपादित करें : PyYAML मृत नहीं है क्योंकि यह निकलता है, यह सिर्फ एक अलग स्थान पर बनाए रखा जाता है।


@ ऑलेक्ज़ेंडर: पायमामल ने पिछले 7 महीनों में काम किया है, और हाल ही में बंद हुआ मुद्दा 12 दिन पहले था। क्या आप कृपया "लंबे मृत" को परिभाषित कर सकते हैं?
अबल्टर

@abalter I माफी माँगता हूँ, ऐसा लगता है कि मुझे उनकी आधिकारिक साइट या पोस्ट के बारे में जानकारी मिली है यहाँ stackoverflow.com/a/36760452/5510526
ऑलेक्ज़ेंडर ज़ेलेंतोव

@ ओलेक्ज़ेंडरज़ेलेंटोसेव मैं भ्रम देख सकता हूं। मृत होने पर लूंग काल था। github.com/yaml/pyyaml/graphs/contributors । हालांकि, उनकी साइट आईएस अप है और पाइएमल के निधन का जिक्र करते हुए एसओ पोस्ट के बाद जारी किए गए रिलीज को दिखाती है। इसलिए यह कहना उचित है कि इस बिंदु पर यह अभी भी जीवित है, हालांकि यह खंडहर के सापेक्ष दिशा स्पष्ट रूप से अनिश्चित है। एएलएसओ, हाल के पदों के साथ यहां एक लंबी चर्चा हुई। मैंने एक टिप्पणी जोड़ी, और अब मेरा केवल एक ही है। मुझे लगता है कि मुझे समझ नहीं आया कि बंद मुद्दे कैसे काम करते हैं। github.com/yaml/pyyaml/issues/145
abalter

@abalter FWIW, जब उस जवाब को पोस्ट किया गया था, अतीत में कुल 9 कमिट थे ... सिर्फ 7 साल से कम। उनमें से एक खराब व्याकरण का एक स्वचालित "फिक्स" था। दो में बमुश्किल बदले हुए नए संस्करण को जारी करना शामिल था। बाकी अपेक्षाकृत छोटे ट्वीक्स थे, ज्यादातर उत्तर से पांच साल पहले बने थे । सभी लेकिन स्वचालित सुधार एक व्यक्ति द्वारा किया गया था। मैं उस जवाब का न्याय नहीं करूंगा जो PyYAML को "लंबे समय तक मृत" कहने के लिए कठोर जवाब देता है।
निधि मोनिका का मुकदमा

-1
#!/usr/bin/env python

import sys
import yaml

def main(argv):

    with open(argv[0]) as stream:
        try:
            #print(yaml.load(stream))
            return 0
        except yaml.YAMLError as exc:
            print(exc)
            return 1

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))

1
यह कोड वास्तव में कुछ भी नहीं करता है। क्या आपका मतलब कोड कमेंट करना था?
काउलविनेटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.