Ricerca nel sito web

Usa Python per analizzare i file di configurazione


Il primo passo è scegliere un formato di configurazione: INI, JSON, YAML o TOML.

A volte, un programma necessita di parametri sufficienti e inserirli tutti come argomenti della riga di comando o variabili d'ambiente non è piacevole né fattibile. In questi casi, ti consigliamo di utilizzare un file di configurazione.

Esistono diversi formati popolari per i file di configurazione. Tra questi ci sono il venerabile (sebbene a volte sottodefinito) formato INI, il formato popolare ma a volte difficile da scrivere a mano JSON, il formato esteso ma a volte sorprendente nei dettagli YAML e l'ultima aggiunta, TOML, di cui molte persone non hanno ancora sentito parlare.

Il tuo primo compito è scegliere un formato e quindi documentare tale scelta. Una volta completata questa parte semplice, è il momento di analizzare la configurazione.

A volte è una buona idea avere una classe che corrisponda ai dati "astratti" nella configurazione. Poiché questo codice non farà nulla con la configurazione, questo è il modo più semplice per mostrare la logica di analisi.

Immagina la configurazione di un processore di file: include una directory di input, una directory di output e quali file raccogliere.

La definizione astratta per la classe di configurazione potrebbe assomigliare a:

from __future__ import annotations
import attr

@attr.frozen
class Configuration:
    @attr.frozen
    class Files:
        input_dir: str
        output_dir: str
    files: Files
    @attr.frozen
    class Parameters:
        patterns: List[str]
    parameters: Parameters

Per rendere più semplice il codice specifico del formato, scriverai anche una funzione per analizzare questa classe dai dizionari. Tieni presente che ciò presuppone che la configurazione utilizzi trattini, non caratteri di sottolineatura. Questo tipo di discrepanza non è raro.

def configuration_from_dict(details):
    files = Configuration.Files(
        input_dir=details["files"]["input-dir"],
        output_dir=details["files"]["output-dir"],
    )
    parameters = Configuration.Paraneters(
        patterns=details["parameters"]["patterns"]
    )
    return Configuration(
        files=files,
        parameters=parameters,
    )

JSON

JSON (JavaScript Object Notation) è un formato simile a JavaScript.

Ecco un esempio di configurazione in formato JSON:

json_config = """
{
    "files": {
        "input-dir": "inputs",
        "output-dir": "outputs"
    },
    "parameters": {
        "patterns": [
            "*.txt",
            "*.md"
        ]
    }
}
"""

La logica di analisi analizza il JSON nelle strutture dati integrate di Python (dizionari, elenchi, stringhe) utilizzando il modulo json e quindi crea la classe dal dizionario:

import json
def configuration_from_json(data):
    parsed = json.loads(data)
    return configuration_from_dict(parsed)

INI

Il formato INI, originariamente popolare su Windows, è diventato di fatto uno standard di configurazione.

Ecco la stessa configurazione di un INI:

ini_config="""
[files]
input-dir = inputs
output-dir = outputs

[parameters]
patterns = ['*.txt', '*.md']
"""

Python può analizzarlo utilizzando il modulo configparser integrato. Il parser si comporta come un oggetto simile a dict, quindi può essere passato direttamente a configuration_from_dict:

import configparser

def configuration_from_ini(data):
    parser = configparser.ConfigParser()
    parser.read_string(data)
    return configuration_from_dict(parser)

YAML

YAML (Yet Another Markup Language) è un'estensione di JSON progettata per essere più facile da scrivere a mano. Ciò avviene, in parte, avendo una specifica lunga.

Ecco la stessa configurazione in YAML:

yaml_config = """
files:
  input-dir: inputs
  output-dir: outputs
parameters:
  patterns:
  - '*.txt'
  - '*.md'
"""

Affinché Python possa analizzarlo, dovrai installare un modulo di terze parti. Il più popolare è PyYAML (pip install pyyaml). Il parser YAML restituisce anche tipi di dati Python integrati che possono essere passati a configuration_from_dict. Tuttavia, il parser YAML prevede un flusso, quindi è necessario convertire la stringa in un flusso.

import io
import yaml
def configuration_from_yaml(data):
    fp = io.StringIO(data)
    parsed = yaml.safe_load(fp)
    return configuration_from_dict(parsed)

TOML

TOML (Tom's Own Markup Language) è progettato per essere un'alternativa leggera a YAML. La specifica è più breve ed è già popolare in alcuni luoghi (ad esempio, il gestore di pacchetti di Rust, Cargo, la usa per la configurazione dei pacchetti).

Ecco la stessa configurazione di TOML:

toml_config = """
[files]
input-dir = "inputs"
output-dir = "outputs"

[parameters]
patterns = [ "*.txt", "*.md",]
"""

Per analizzare TOML, è necessario installare un pacchetto di terze parti. Il più popolare si chiama, semplicemente, toml. Come YAML e JSON, restituisce tipi di dati Python di base.

import toml
def configuration_from_toml(data):
    parsed = toml.loads(data)
    return configuration_from_dict(parsed)

Riepilogo

La scelta di un formato di configurazione è un sottile compromesso. Tuttavia, una volta presa la decisione, Python può analizzare la maggior parte dei formati più diffusi utilizzando una manciata di righe di codice.

Articoli correlati: