Python è ampiamente utilizzato per la sua flessibilità e facilità d’uso in molteplici applicazioni. Tra queste, la possibilità di eseguire script dalla riga di comando è particolarmente utile in numerosi contesti. Ad esempio, è possibile eseguire script di elaborazione dei dati con argomenti o utilizzarli come parte di attività di automazione. Inoltre, utilizzando gli argomenti della riga di comando, è possibile modificare il comportamento degli script e creare soluzioni più generiche e versatili. In questo articolo, esploreremo come gestire gli argomenti della riga di comando in Python, coprendo sia le tecniche di base che quelle avanzate.
Fondamenti degli argomenti della riga di comando
Quando si esegue uno script Python dalla riga di comando, è possibile passare degli argomenti per controllarne il comportamento. Il modo più semplice per farlo è utilizzare sys.argv
.
Cosa è sys.argv
sys.argv
è un elenco fornito dal modulo sys
, che fa parte della libreria standard di Python, e contiene gli argomenti passati alla riga di comando. Il primo elemento della lista (sys.argv[0]
) è il nome dello script, mentre gli elementi successivi rappresentano gli argomenti passati.
Esempio base di utilizzo
Il seguente script è un esempio semplice che visualizza gli argomenti passati:
import sys
if __name__ == "__main__":
print("Nome dello script:", sys.argv[0])
print("Argomenti:", sys.argv[1:])
Quando esegui lo script con python script.py arg1 arg2
, otterrai il seguente output:
Nome dello script: script.py
Argomenti: ['arg1', 'arg2']
Le difficoltà nell’analisi degli argomenti
Anche se sys.argv
è un modo semplice per acquisire gli argomenti, presenta alcune difficoltà:
- È necessario validare manualmente il numero e il tipo degli argomenti.
- La gestione delle opzioni (ad esempio
--help
) diventa complicata. - Il codice per la gestione di una lunga lista di argomenti diventa complesso.
Per risolvere questi problemi, Python offre moduli come argparse
, che semplificano l’analisi degli argomenti. Nel prossimo paragrafo vedremo come usare argparse
.
Panoramica sul modulo argparse
Il modulo argparse
fa parte della libreria standard di Python ed è uno strumento potente per analizzare facilmente gli argomenti della riga di comando. Usando questo modulo, è possibile definire argomenti e opzioni in modo semplice e analizzarli al momento dell’esecuzione dello script.
Struttura di base di argparse
La sequenza base per usare argparse
è la seguente:
- Creazione dell’oggetto ArgumentParser
Creare un oggetto di base per analizzare gli argomenti. - Definizione degli argomenti
Specifica gli argomenti e le opzioni che lo script può ricevere. - Analisi degli argomenti
Analizza gli argomenti passati e usa i valori per controllare l’esecuzione del programma.
Esempio base di utilizzo
Il seguente script mostra un esempio di come analizzare gli argomenti utilizzando argparse
:
import argparse
if __name__ == "__main__":
# Creazione dell'oggetto ArgumentParser
parser = argparse.ArgumentParser(description="Esempio base di analisi degli argomenti")
# Aggiunta degli argomenti
parser.add_argument("name", help="Specifica il nome utente")
parser.add_argument("--age", type=int, help="Specifica l'età")
# Analisi degli argomenti
args = parser.parse_args()
# Visualizzazione dei risultati
print(f"Ciao, {args.name}!")
if args.age:
print(f"La tua età è {args.age}.")
Per eseguire questo script, usa il seguente comando:
python script.py Alice --age 30
L’output sarà il seguente:
Ciao, Alice!
La tua età è 30.
Vantaggi principali di argparse
- Verifica automatica del tipo degli argomenti: è possibile verificare automaticamente il tipo di valori passati, come numeri o stringhe.
- Messaggi di aiuto predefiniti: aggiunge automaticamente l’opzione
--help
e genera messaggi che spiegano come usare lo script. - Gestione di configurazioni complesse: supporta vari tipi di argomenti, come obbligatori, facoltativi, flag, e sottocomandi.
Nel prossimo paragrafo vedremo come configurare gli argomenti opzionali in modo più avanzato.
Configurazione degli argomenti opzionali
Utilizzando il modulo argparse
, è possibile configurare gli argomenti della riga di comando in modo flessibile e gestire opzioni specifiche. Gli argomenti opzionali sono quelli che possono essere specificati facoltativamente per modificare il comportamento dello script, e solitamente iniziano con --
o -
.
Configurazione base degli argomenti opzionali
Gli argomenti opzionali possono essere aggiunti utilizzando il metodo add_argument
, specificando il nome con --
o -
.
Ecco un esempio base di configurazione di argomenti opzionali:
import argparse
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Esempio base di argomenti opzionali")
# Aggiunta di argomenti opzionali
parser.add_argument("--verbose", action="store_true", help="Abilita la modalità verbose")
parser.add_argument("--output", type=str, help="Specifica il nome del file di output")
args = parser.parse_args()
if args.verbose:
print("Modalità verbose abilitata")
if args.output:
print(f"File di output: {args.output}")
Per eseguire questo script, usa il comando:
python script.py --verbose --output result.txt
L’output sarà:
Modalità verbose abilitata
File di output: result.txt
Principali opzioni di configurazione
Quando si personalizzano gli argomenti opzionali, i principali parametri da configurare sono i seguenti:
1. Specifica del tipo
Utilizzando il parametro type
, è possibile specificare il tipo del valore che l’argomento accetta.
parser.add_argument("--count", type=int, help="Specifica il numero di iterazioni")
2. Valori di default
Il parametro default
permette di impostare un valore predefinito per un argomento se non viene specificato durante l’esecuzione.
parser.add_argument("--level", type=int, default=1, help="Specifica il livello di elaborazione (predefinito: 1)")
3. Argomenti obbligatori
Impostando required=True
, è possibile rendere un argomento opzionale obbligatorio.
parser.add_argument("--config", required=True, help="Specifica il file di configurazione")
Gestione dei flag
Alcuni argomenti opzionali non richiedono valori, ma modificano il comportamento dello script quando specificati. Per questi, si utilizza action="store_true"
:
parser.add_argument("--debug", action="store_true", help="Abilita la modalità di debug")
Quando esegui lo script con --debug
, args.debug
sarà impostato su True
.
Riepilogo
Utilizzando argparse
, è possibile creare facilmente argomenti opzionali flessibili e facili da usare. Nel prossimo paragrafo, esploreremo come gestire gli argomenti obbligatori e i valori di default.
Utilizzo degli argomenti obbligatori e dei valori di default
Con argparse
, è possibile rendere alcuni argomenti obbligatori o configurare valori di default che vengono utilizzati se un argomento non viene specificato. Queste opzioni consentono di creare script più flessibili e robusti.
Configurazione degli argomenti obbligatori
Per impostazione predefinita, gli argomenti opzionali (quelli che iniziano con --
) sono facoltativi. Tuttavia, se si desidera rendere un argomento obbligatorio, è necessario impostare required=True
.
Esempio di utilizzo
Nel seguente esempio, l’opzione --config
è obbligatoria:
import argparse
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Esempio di argomento obbligatorio")
# Aggiunta di un argomento obbligatorio
parser.add_argument("--config", required=True, help="Specifica il file di configurazione")
args = parser.parse_args()
print(f"File di configurazione: {args.config}")
Se esegui lo script senza specificare l’argomento, verrà generato un errore:
python script.py
usage: script.py --config CONFIG
script.py: error: the following arguments are required: --config
Se esegui lo script specificando --config
, funzionerà correttamente:
python script.py --config settings.json
File di configurazione: settings.json
Impostazione dei valori di default
È possibile configurare un valore di default per un argomento, in modo che venga utilizzato se l’argomento non è stato specificato durante l’esecuzione.
Esempio di utilizzo
Nel seguente esempio, l’opzione --log-level
ha un valore di default:
import argparse
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Esempio di valori di default")
# Aggiunta di un'opzione con valore di default
parser.add_argument("--log-level", default="INFO", help="Livello di dettaglio dei log (default: INFO)")
args = parser.parse_args()
print(f"Livello di log: {args.log_level}")
Se esegui lo script senza specificare alcun argomento, verrà utilizzato il valore di default:
python script.py
Livello di log: INFO
Se invece specifichi --log-level
, il suo valore avrà la precedenza:
python script.py --log-level DEBUG
Livello di log: DEBUG
Combinazione di argomenti obbligatori e valori di default
È anche possibile combinare argomenti obbligatori e valori di default, anche se normalmente si evita di usare valori di default per argomenti di posizione e si preferisce richiederli esplicitamente all’utente.
Esempio di utilizzo
parser.add_argument("filename", help="Specifica il nome del file di destinazione")
In questo caso, filename
è obbligatorio e deve essere sempre specificato durante l’esecuzione dello script.
Riepilogo
Impostando correttamente gli argomenti obbligatori e i valori di default, è possibile migliorare la flessibilità e l’usabilità dello script. Nel prossimo paragrafo, esploreremo come argparse
può generare automaticamente i messaggi di aiuto per gli utenti.
Generazione automatica dei messaggi di aiuto
Il modulo argparse
è in grado di generare automaticamente messaggi di aiuto per gli argomenti della riga di comando. Questo permette di fornire una guida intuitiva agli utenti su come utilizzare lo script.
Messaggi di aiuto di base
Quando si crea un ArgumentParser
, l’opzione --help
o -h
viene aggiunta automaticamente e fornisce una descrizione degli argomenti disponibili.
Esempio: Messaggio di aiuto generato automaticamente
Il seguente script genera automaticamente un messaggio di aiuto quando viene eseguito con l’opzione --help
:
import argparse
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Esempio di messaggio di aiuto")
parser.add_argument("--input", help="Specifica il file di input")
parser.add_argument("--output", help="Specifica il file di output")
parser.add_argument("--verbose", action="store_true", help="Abilita la modalità verbose")
args = parser.parse_args()
Quando esegui lo script con l’opzione --help
, otterrai il seguente messaggio:
python script.py --help
usage: script.py [-h] [--input INPUT] [--output OUTPUT] [--verbose]
Esempio di messaggio di aiuto
options:
-h, --help Mostra questo messaggio di aiuto e termina
--input INPUT Specifica il file di input
--output OUTPUT Specifica il file di output
--verbose Abilita la modalità verbose
Il messaggio di aiuto include i nomi degli argomenti e una descrizione di ciascuno. È possibile utilizzare sia -h
che --help
per ottenere lo stesso risultato.
Personalizzazione del messaggio di aiuto
Con argparse
, è possibile personalizzare la descrizione degli argomenti e dei messaggi di aiuto.
1. Impostazione della descrizione dello script
Usando il parametro description
di ArgumentParser
, è possibile fornire una descrizione generale dello script:
parser = argparse.ArgumentParser(description="Questo script elabora i file")
2. Descrizione per ciascun argomento
Con il parametro help
di add_argument
, è possibile aggiungere una descrizione per ogni argomento:
parser.add_argument("--input", help="Specifica il file di input da elaborare")
3. Aggiunta di esempi personalizzati
Usando il parametro epilog
, è possibile aggiungere esempi di utilizzo o altre informazioni aggiuntive alla fine del messaggio di aiuto:
parser = argparse.ArgumentParser(
description="Esempio di messaggio di aiuto",
epilog="Esempio: python script.py --input file.txt --output result.txt"
)
Esempio: Messaggio di aiuto personalizzato
import argparse
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Questo script elabora i file",
epilog="Esempio: python script.py --input in.txt --output out.txt"
)
parser.add_argument("--input", required=True, help="Specifica il file di input")
parser.add_argument("--output", required=True, help="Specifica il file di output")
parser.add_argument("--verbose", action="store_true", help="Abilita la modalità verbose")
args = parser.parse_args()
usage: script.py [-h] --input INPUT --output OUTPUT [--verbose]
Questo script elabora i file
options:
-h, --help Mostra questo messaggio di aiuto e termina
--input INPUT Specifica il file di input
--output OUTPUT Specifica il file di output
--verbose Abilita la modalità verbose
Esempio: python script.py --input in.txt --output out.txt
Vantaggi del messaggio di aiuto
- Facilità d’uso: Gli utenti possono comprendere rapidamente come utilizzare lo script.
- Coerenza: Tutte le descrizioni degli argomenti vengono presentate in un formato uniforme.
- Manutenibilità: I messaggi di aiuto vengono aggiornati automaticamente quando vengono apportate modifiche al codice.
Nel prossimo paragrafo, esamineremo come introdurre i sottocomandi in uno script per supportare più azioni.
Introduzione ai sottocomandi
Gli script con più funzionalità possono dividere le azioni in comandi separati, utilizzando la funzionalità di sottocomandi di argparse
. Questo approccio aiuta a organizzare lo script e rende l’uso più chiaro.
Struttura base di un sottocomando
Per utilizzare i sottocomandi, si usa il metodo add_subparsers
. Questo metodo consente di definire i sottocomandi e di associare loro argomenti e opzioni specifiche.
Esempio: Struttura di un sottocomando
Il seguente esempio mostra uno script con due sottocomandi: add
e delete
:
import argparse
if __name__ == "__main__":
# Creazione dell'ArgumentParser principale
parser = argparse.ArgumentParser(description="Esempio di sottocomandi")
# Creazione di subparsers per i sottocomandi
subparsers = parser.add_subparsers(dest="command", help="Comandi disponibili")
# Definizione del sottocomando 'add'
parser_add = subparsers.add_parser("add", help="Aggiungi un elemento")
parser_add.add_argument("item", help="Nome dell'elemento da aggiungere")
# Definizione del sottocomando 'delete'
parser_delete = subparsers.add_parser("delete", help="Elimina un elemento")
parser_delete.add_argument("item", help="Nome dell'elemento da eliminare")
# Analisi degli argomenti
args = parser.parse_args()
# Azioni in base al sottocomando scelto
if args.command == "add":
print(f"Elemento '{args.item}' aggiunto")
elif args.command == "delete":
print(f"Elemento '{args.item}' eliminato")
else:
parser.print_help()
Per eseguire questo script, usa i seguenti comandi:
python script.py add "Task 1"
Output:
Elemento 'Task 1' aggiunto
python script.py delete "Task 1"
Output:
Elemento 'Task 1' eliminato
Argomenti e opzioni nei sottocomandi
Ogni sottocomando può avere i propri argomenti e opzioni. Ad esempio, è possibile aggiungere un’opzione di descrizione per il sottocomando add
o una flag di conferma per il sottocomando delete
.
Esempio di sottocomando espanso
# Aggiunta di un'opzione di descrizione per il sottocomando 'add'
parser_add.add_argument("--description", help="Descrizione dell'elemento")
# Aggiunta di un flag di conferma per il sottocomando 'delete'
parser_delete.add_argument("--force", action="store_true", help="Elimina senza conferma")
Per eseguire questo script, puoi usare i seguenti comandi:
python script.py add "Task 2" --description "Questo è un nuovo task"
python script.py delete "Task 2" --force
Considerazioni sull’uso dei sottocomandi
- Progettazione coerente
Quando si utilizzano più sottocomandi, è importante mantenere una progettazione coerente dei nomi dei comandi e degli argomenti.
Riepilogo
L’uso dei sottocomandi consente di implementare in modo compatto più funzionalità all’interno dello stesso script. Questo è particolarmente utile per strumenti complessi come gestori di task o client API. Nel prossimo paragrafo, esploreremo come il modulo click
può rendere l’analisi degli argomenti ancora più flessibile.
Analisi delle opzioni con la libreria click
Il modulo argparse
è potente, ma per creare strumenti a riga di comando più semplici e intuitivi, la libreria click
è una scelta eccellente. click
consente di definire l’analisi degli argomenti e la generazione automatica dei messaggi di aiuto in modo conciso.
Fondamenti di click
click
utilizza i decoratori di funzione per definire argomenti e opzioni. Questo approccio rende il codice più leggibile e consente di separare le funzionalità in modo naturale.
Installazione di click
Inizia installando la libreria:
pip install click
Esempio base di utilizzo
Il seguente esempio mostra come usare click
per analizzare gli argomenti della riga di comando:
import click
@click.command()
@click.option("--name", prompt="Your name", help="Specifica il nome utente")
@click.option("--age", default=25, help="Specifica l'età (default: 25)")
def greet(name, age):
"""Mostra un messaggio di saluto"""
click.echo(f"Ciao, {name}! Hai {age} anni.")
if __name__ == "__main__":
greet()
Per eseguire questo script, usa il comando:
python script.py --name Alice --age 30
Output:
Ciao, Alice! Hai 30 anni.
--name
e --age
se non specificati richiederanno l’inserimento da parte dell’utente tramite il prompt.
Strumenti con più comandi
Con click
, è facile gestire più comandi in uno stesso script. Si può usare il decoratore @click.group()
per raccogliere più comandi in un unico programma.
Esempio: Più comandi
import click
@click.group()
def cli():
"""Gestisce più comandi"""
pass
@click.command()
@click.argument("item")
def add(item):
"""Aggiungi un elemento"""
click.echo(f"Elemento '{item}' aggiunto")
@click.command()
@click.argument("item")
def delete(item):
"""Elimina un elemento"""
click.echo(f"Elemento '{item}' eliminato")
cli.add_command(add)
cli.add_command(delete)
if __name__ == "__main__":
cli()
Questo script consente di eseguire i comandi nel seguente modo:
python script.py add "Task 1"
python script.py delete "Task 1"
Output:
Elemento 'Task 1' aggiunto
Elemento 'Task 1' eliminato
Vantaggi di click
- Codice conciso: La definizione degli argomenti e delle opzioni è intuitiva grazie ai decoratori.
- Generazione automatica dell’aiuto:
--help
è generato automaticamente. - Prompt per l’input: con il parametro
prompt
, l’utente può inserire un valore quando non specificato. - Decorazioni e colori: Con
click.echo()
è possibile aggiungere facilmente decorazioni e colori ai messaggi di output.
Esempio di gestione degli errori
click semplifica anche la gestione degli errori. Ad esempio, è possibile personalizzare i messaggi di errore:
@click.command()
@click.argument("number", type=int)
def square(number):
"""Calcola il quadrato del numero specificato"""
if number < 0:
raise click.BadParameter("Specifica un numero positivo")
click.echo(f"Il quadrato di {number} è {number**2}")
if __name__ == "__main__":
square()
Riepilogo
click
è una libreria flessibile che consente di creare sia strumenti semplici a riga di comando che applicazioni complesse con strutture a sottocomando. Nel prossimo paragrafo, esploreremo le migliori pratiche per lo sviluppo di strumenti a riga di comando.
Migliori pratiche per lo sviluppo di strumenti a riga di comando
Quando si sviluppano strumenti a riga di comando in Python, è fondamentale considerare la facilità d'uso e l'espandibilità del design. In questa sezione, esploreremo alcune delle migliori pratiche per creare strumenti di comando efficaci.
1. Interfaccia intuitiva e coerente
Progettare un'interfaccia semplice e coerente è cruciale per evitare confusione tra gli utenti.
Punti consigliati
- Utilizzare nomi di comandi e opzioni chiari e comprensibili (ad esempio,
--verbose
). - Definire abbreviazioni per opzioni lunghe (ad esempio,
--help
e-h
). - Organizzare i sottocomandi e le opzioni in modo gerarchico, in modo che siano logicamente raggruppati.
Esempio
tool.py add "task name" --priority high
tool.py delete "task name" --force
2. Utilizzo dell'aiuto generato automaticamente
Aggiungere descrizioni appropriate per ogni argomento e opzione migliora la qualità dei messaggi di aiuto, rendendo il comando facilmente comprensibile per gli utenti.
Approccio consigliato
- Aggiungere descrizioni appropriate per ogni argomento usando
help
. - Fornire una descrizione generale dello script e esempi d'uso tramite
description
edepilog
.
Esempio: Impostazione di argparse
parser = argparse.ArgumentParser(
description="Strumento di gestione dei task",
epilog="Uso: python tool.py add 'task' --priority high"
)
3. Implementazione della gestione degli errori
Fornire messaggi di errore chiari e precisi quando l'utente fornisce argomenti non validi migliora la robustezza dello script.
Esempio di gestione degli errori
@click.command()
@click.argument("number", type=int)
def square(number):
if number < 0:
raise click.BadParameter("I numeri negativi non sono supportati")
click.echo(f"Il quadrato di {number} è {number**2}")
4. Strutturazione del tool in moduli
Quando lo script diventa complesso, è utile dividerlo in moduli separati per semplificarne la gestione.
Esempio di struttura
project/
├── cli.py # Interfaccia a riga di comando
├── commands/
│ ├── add.py # Comando 'add'
│ ├── delete.py # Comando 'delete'
│ └── __init__.py
├── utils.py # Funzioni di utilità
└── main.py # Punto di ingresso
5. Implementazione dei test unitari
Aggiungere test ai comandi a riga di comando assicura una maggiore affidabilità dello strumento.
Esempio di test
Usa pytest
per testare gli script a riga di comando:
from click.testing import CliRunner
from my_tool import cli
def test_add_command():
runner = CliRunner()
result = runner.invoke(cli, ["add", "Task 1"]])
assert result.exit_code == 0
assert "Task 1 aggiunto" in result.output
6. Compatibilità cross-platform
Progettare il tool per essere compatibile con Windows, macOS e Linux assicura che possa essere utilizzato su diverse piattaforme.
Considerazioni
- Utilizzare
os.path
opathlib
per gestire i percorsi dei file. - Utilizzare
subprocess
per chiamare comandi esterni o programmi.
7. Semplificazione della distribuzione e installazione
Per rendere il tool facilmente utilizzabile su altri ambienti, è fondamentale pianificare la sua imballatura e installazione.
Metodi consigliati
- Usare
setuptools
per impacchettare lo strumento in un pacchetto Python. - Definire i
entry_points
per rendere lo strumento installabile come un comando da terminale.
from setuptools import setup
setup(
name="my_tool",
version="1.0",
py_modules=["tool"],
install_requires=["click"],
entry_points={
"console_scripts": [
"tool=tool:cli",
],
},
)
Riepilogo
Quando sviluppi strumenti a riga di comando, è importante concentrarsi su facilità d'uso, espandibilità e manutenibilità. Progettando con attenzione, sarà possibile creare strumenti intuitivi sia per gli utenti che per gli sviluppatori.