Jak parsować plik YAML w Pythonie?
Jak parsować plik YAML w Pythonie?
Odpowiedzi:
Najłatwiejszą i najczystszą metodą bez polegania na nagłówkach C jest PyYaml ( dokumentacja ), którą można zainstalować za pomocą 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)
I to wszystko. Istnieje yaml.load()
również prosta funkcja, ale yaml.safe_load()
zawsze powinna być preferowana, chyba że jawnie potrzebujesz dostarczonej serializacji / deserializacji dowolnego obiektu, aby uniknąć wprowadzenia możliwości wykonania dowolnego kodu.
Uwaga: projekt PyYaml obsługuje wersje do specyfikacji YAML 1.1 . Jeśli wymagana jest obsługa specyfikacji YAML 1.2 , zobacz ruamel.yaml, jak wspomniano w tej odpowiedzi .
pip install pyyaml
, zobacz ten post, aby uzyskać więcej opcji stackoverflow.com/questions/14261614/…
# -*- 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)
a list:
- 1
- 42
- 3.141
- 1337
- help
- €
a string: bla
another dict:
foo: bar
key: value
the answer: 42
.yml
i .yaml
W przypadku aplikacji ważne mogą być:
Zobacz także: Porównanie formatów serializacji danych
Jeśli szukasz sposobu na utworzenie plików konfiguracyjnych, możesz przeczytać mój krótki artykuł Pliki konfiguracyjne w Pythonie
€
w systemie Windows to €
. Czy ktoś zna przyczynę?
io.open(doc_name, 'r', encoding='utf8')
aby odczytać znak specjalny. Wersja YAML 0.1.7
open(doc_name, ..., encodung='utf8')
do odczytu i zapisu, bez importowania io
.
Jeśli masz YAML, który jest zgodny ze specyfikacją YAML 1.2 (wydaną w 2009 r.), Powinieneś użyć ruamel.yaml (zrzeczenie się: Jestem autorem tego pakietu). Jest to w zasadzie nadzbiór PyYAML, który obsługuje większość YAML 1.1 (od 2005).
Jeśli chcesz zachować swoje komentarze podczas podróży w obie strony, z pewnością powinieneś użyć ruamel.yaml.
Aktualizacja przykładu @ Jona jest łatwa:
import ruamel.yaml as yaml
with open("example.yaml") as stream:
try:
print(yaml.safe_load(stream))
except yaml.YAMLError as exc:
print(exc)
Używaj, safe_load()
chyba że naprawdę masz pełną kontrolę nad danymi wejściowymi, potrzebujesz ich (rzadko w przypadku) i wiesz, co robisz.
Jeśli używasz pathlib Path
do manipulowania plikami, lepiej jest użyć nowego interfejsu API ruamel.yaml zapewnia:
from ruamel.yaml import YAML
from pathlib import Path
path = Path('example.yaml')
yaml = YAML(typ='safe')
data = yaml.load(path)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 926: ordinal not in range(128)
). Próbowałem ustawić yaml.encoding na utf-8, ale nie działałem, ponieważ metoda ładowania w YAML nadal używa ascii_decode. Czy to błąd?
Najpierw zainstaluj pyyaml za pomocą pip3.
Następnie zaimportuj moduł yaml i załaduj plik do słownika o nazwie „my_dict”:
import yaml
with open('filename.yaml') as f:
my_dict = yaml.safe_load(f)
To wszystko czego potrzebujesz. Teraz cały plik yaml znajduje się w słowniku „my_dict”.
!!python
), może być również niebezpieczny (jak w przypadku całkowitego wyczyszczenia dysku twardego) yaml.load()
. Ponieważ jest to wyraźnie udokumentowane, powinieneś powtórzyć to ostrzeżenie tutaj (w prawie wszystkich przypadkach yaml.safe_load()
można użyć).
import yaml
, ale to nie jest wbudowany moduł i nie określasz, który to pakiet. Uruchomienie import yaml
nowej instalacji Python3 powodujeModuleNotFoundError: No module named 'yaml'
Przykład:
defaults.yaml
url: https://www.google.com
environment.py
from ruamel import yaml
data = yaml.safe_load(open('defaults.yaml'))
data['url']
Używam ruamel.yaml . Szczegóły i debata tutaj .
from ruamel import yaml
with open(filename, 'r') as fp:
read_data = yaml.load(fp)
Użycie ruamel.yaml jest kompatybilne (z pewnymi prostymi rozwiązalnymi problemami) ze starymi zastosowaniami PyYAML i jak podano w linku, który podałem , użyj
from ruamel import yaml
zamiast
import yaml
i naprawi większość twoich problemów.
EDYCJA : PyYAML nie jest martwy, jak się okazuje, po prostu jest trzymany w innym miejscu.
#!/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:]))
yaml.safe_load
ponieważ nie może wykonać dowolnego kodu z pliku YAML.