Manipularea fișierelor yaml utilizând Python

Manipularea fișierelor yaml utilizând Python


YAML (YAML Ain't Markup Language) este un format de serializare a datelor ușor de citit și scris, similar cu JSON sau XML. În Python, YAML poate fi utilizat pentru a citi și scrie configurații, date structurate și alte informații. În această lecție, vom explora cum să utilizăm biblioteca PyYAML pentru a lucra cu fișiere YAML în Python.

Citirea Fișierelor YAML

Să presupunem că avem un fișier YAML numit config.yaml cu următorul conținut:

database:
  host: localhost
  port: 5432
  username: user
  password: pass

logging:
  level: INFO
  format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'


Pentru a citi acest fișier în Python, vom folosi următorul cod:

import yaml

# Deschidem fișierul YAML
with open('config.yaml', 'r') as file:
    config = yaml.safe_load(file)

# Afișăm conținutul fișierului YAML
print(config)


Importarea bibliotecii YAML:

import yaml


Aceasta linie importă biblioteca PyYAML în programul nostru.

Deschiderea fișierului YAML:

with open('config.yaml', 'r') as file:


Utilizăm context manager-ul with pentru a deschide fișierul config.yaml în modul citire ('r').

Încărcarea conținutului fișierului YAML:

config = yaml.safe_load(file)


Funcția yaml.safe_load citește conținutul fișierului și îl convertește într-un obiect Python (de obicei un dicționar).

Afișarea conținutului:

print(config)


Aceasta linie afișează dicționarul rezultat.

Scrierea Fișierelor YAML

Putem de asemenea să scriem date structurate într-un fișier YAML. Să considerăm următorul dicționar:

config_data = {
    'database': {
        'host': 'localhost',
        'port': 5432,
        'username': 'user',
        'password': 'pass'
    },
    'logging': {
        'level': 'INFO',
        'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    }
}


Pentru a scrie acest dicționar într-un fișier YAML, utilizăm următorul cod:

import yaml

# Deschidem fișierul YAML în modul scriere
with open('config.yaml', 'w') as file:
    yaml.dump(config_data, file)


Deschiderea fișierului YAML în modul scriere:

with open('config.yaml', 'w') as file:


Utilizăm context manager-ul with pentru a deschide fișierul config.yaml în modul scriere ('w').

Scrierea dicționarului în fișierul YAML:

yaml.dump(config_data, file)


Funcția yaml.dump scrie conținutul dicționarului config_data în fișierul YAML.

Manipularea Datelor YAML

Citirea și Modificarea Datelor

Să citim fișierul YAML, să modificăm un atribut și să scriem modificările înapoi în fișier.

import yaml

# Citirea fișierului YAML
with open('config.yaml', 'r') as file:
    config = yaml.safe_load(file)

# Modificarea unui atribut
config['database']['host'] = '127.0.0.1'

# Scrierea modificărilor înapoi în fișier
with open('config.yaml', 'w') as file:
    yaml.dump(config, file)


Citirea fișierului YAML: Aceasta parte este identică cu exemplul anterior de citire a fișierelor YAML.

Modificarea unui atribut:

config['database']['host'] = '127.0.0.1'


Modificăm valoarea atributului host din secțiunea database.

Scrierea modificărilor înapoi în fișier: Aceasta parte este identică cu exemplul anterior de scriere a fișierelor YAML.

Haideți să explorăm câteva funcționalități mai complexe, cum ar fi:

  1. Utilizarea ancorelor și aliasurilor YAML
  2. Gestionarea structurilor complexe de date
  3. Validarea datelor YAML cu schema
  4. Utilizarea constructorilor și reprezentanților personalizați

Utilizarea Ancorelor și Aliasurilor YAML

YAML suportă reutilizarea părților de date folosind ancore (&) și aliasuri (*). Acest lucru este util pentru evitarea duplicării datelor.

Exemplu YAML

defaults: &defaults
  adapter: postgres
  host: localhost

development:
  database: dev_db
  <<: *defaults

production:
  database: prod_db
  <<: *defaults


Citirea și Afișarea YAML cu Ancore și Aliasuri

import yaml

yaml_data = """
defaults: &defaults
  adapter: postgres
  host: localhost

development:
  database: dev_db
  <<: *defaults

production:
  database: prod_db
  <<: *defaults
"""

config = yaml.safe_load(yaml_data)
print(config)


Definirea ancorei &defaults:

    defaults: &defaults
    adapter: postgres
    host: localhost


Utilizarea aliasului <<: *defaults:

    development:
    database: dev_db
    <<: *defaults


Rezultatul

{
  'defaults': {'adapter': 'postgres', 'host': 'localhost'},
  'development': {'database': 'dev_db', 'adapter': 'postgres', 'host': 'localhost'},
  'production': {'database': 'prod_db', 'adapter': 'postgres', 'host': 'localhost'}
}


Gestionarea Structurilor Complexe de Date

YAML poate reprezenta structuri de date complexe, inclusiv liste în cadrul dicționarelor și invers.

Exemplu YAML

databases:
  - name: main_db
    host: localhost
    ports:
      - 5432
      - 5433
  - name: backup_db
    host: backup.local
    ports:
      - 5434

Citirea Structurilor Complexe

import yaml

yaml_data = """
databases:
  - name: main_db
    host: localhost
    ports:
      - 5432
      - 5433
  - name: backup_db
    host: backup.local
    ports:
      - 5434
"""

config = yaml.safe_load(yaml_data)
print(config)


Definirea listei de dicționare:

databases:
      - name: maindb
        host: localhost
        ports:
          - 5432
          - 5433
      - name: backupdb
        host: backup.local
        ports:
          - 5434
    

Rezultatul

{
  'databases': [
    {'name': 'main_db', 'host': 'localhost', 'ports': [5432, 5433]},
    {'name': 'backup_db', 'host': 'backup.local', 'ports': [5434]}
  ]
}


Validarea Datelor YAML cu Schema

Validarea datelor YAML poate fi realizată folosind schema YAML pentru a asigura conformitatea structurii datelor.

Exemplu de Validare

Vom folosi biblioteca cerberus pentru validare.

pip install cerberus


Definirea Schemei și Validarea

import yaml
from cerberus import Validator

yaml_data = """
database:
  host: localhost
  port: 5432
  username: user
  password: pass
"""

config = yaml.safe_load(yaml_data)

schema = {
    'database': {
        'type': 'dict',
        'schema': {
            'host': {'type': 'string'},
            'port': {'type': 'integer', 'min': 1024, 'max': 65535},
            'username': {'type': 'string'},
            'password': {'type': 'string'}
        }
    }
}

v = Validator(schema)
if v.validate(config):
    print("Config valid")
else:
    print("Config invalid", v.errors)


Definirea schemei:

    schema = {
        'database': {
            'type': 'dict',
            'schema': {
                'host': {'type': 'string'},
                'port': {'type': 'integer', 'min': 1024, 'max': 65535},
                'username': {'type': 'string'},
                'password': {'type': 'string'}
            }
        }
    }


Validarea datelor:

    v = Validator(schema)
    if v.validate(config):
        print("Config valid")
    else:
        print("Config invalid", v.errors)


Utilizarea Constructorilor și Reprezentanților Personalizați

Pentru date complexe, putem defini constructori și reprezentanți personalizați.

Definirea unei Clase Personalizate

import yaml

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return f"Person(name={self.name}, age={self.age})"

def person_constructor(loader, node):
    value = loader.construct_mapping(node)
    return Person(**value)

def person_representer(dumper, data):
    return dumper.represent_mapping('!Person', {'name': data.name, 'age': data.age})

yaml.add_constructor('!Person', person_constructor)
yaml.add_representer(Person, person_representer)

yaml_data = """
person: !Person
  name: John Doe
  age: 30
"""

data = yaml.safe_load(yaml_data)
print(data)


Definirea clasei Person:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return f"Person(name={self.name}, age={self.age})"


Definirea constructorului personalizat:

    def person_constructor(loader, node):
        value = loader.construct_mapping(node)
        return Person(**value)


Definirea reprezentantului personalizat:

def person_representer(dumper, data):
    return dumper.represent_mapping('!Person', {'name': data.name, 'age': data.age})

Adăugarea constructorului și reprezentantului:

    yaml.add_constructor('!Person', person_constructor)
    yaml.add_representer(Person, person_representer)


Rezultatul

{'person': Person(name=John Doe, age=30)}


Concluzie

În această lecție avansată, am explorat funcționalități ale YAML în Python, inclusiv:

  • Utilizarea ancorelor și aliasurilor YAML pentru reutilizarea datelor.
  • Gestionarea structurilor complexe de date în YAML.
  • Validarea datelor YAML folosind schema.
  • Utilizarea constructorilor și reprezentanților personalizați pentru date complexe.

Aceste tehnici permit gestionarea eficientă și flexibilă a datelor YAML în proiectele Python, facilitând dezvoltarea și mentenanța aplicațiilor complexe.


Trebuie să fii autentificat pentru a accesa editorul de cod și pentru a experimenta codul prezentat în acest tutorial.

Intră în cont