Specifica il formato per gli argomenti di input argparse python


111

Ho uno script Python che richiede alcuni input della riga di comando e sto usando argparse per analizzarli. Ho trovato la documentazione un po 'confusa e non sono riuscito a trovare un modo per verificare un formato nei parametri di input. Quello che intendo per controllo del formato è spiegato con questo script di esempio:

parser.add_argument('-s', "--startdate", help="The Start Date - format YYYY-MM-DD ", required=True)
parser.add_argument('-e', "--enddate", help="The End Date format YYYY-MM-DD (Inclusive)", required=True)
parser.add_argument('-a', "--accountid", type=int, help='Account ID for the account for which data is required (Default: 570)')
parser.add_argument('-o', "--outputpath", help='Directory where output needs to be stored (Default: ' + os.path.dirname(os.path.abspath(__file__)))

Devo controllare l'opzione -se -eche l'input dell'utente sia nel formato YYYY-MM-DD. C'è un'opzione in argparse che non conosco quale compia questo.

Risposte:


235

Secondo la documentazione :

L' typeargomento parola chiave di add_argument()consente di eseguire qualsiasi controllo di tipo e conversione di tipo necessario ... type=può accettare qualsiasi chiamabile che accetta un singolo argomento di stringa e restituisce il valore convertito

Potresti fare qualcosa come:

def valid_date(s):
    try:
        return datetime.strptime(s, "%Y-%m-%d")
    except ValueError:
        msg = "Not a valid date: '{0}'.".format(s)
        raise argparse.ArgumentTypeError(msg)

Quindi usalo come type:

parser.add_argument("-s", 
                    "--startdate", 
                    help="The Start Date - format YYYY-MM-DD", 
                    required=True, 
                    type=valid_date)

Riguardo all'altra domanda che hai modificato, puoi indicarmi la documentazione (se presente) per questo?
Sohaib

Presume che valid_date()l'argomento specificato sia una stringa?
Stevoisiak

1
@StevenVascellaro si, ma è quello che definisce l'API; "accetta un singolo argomento stringa" per citazione dalla documentazione.
jonrsharpe

71

Solo per aggiungere alla risposta sopra, puoi usare una funzione lambda se vuoi mantenerla su una riga. Per esempio:

parser.add_argument('--date', type=lambda d: datetime.strptime(d, '%Y%m%d'))

Vecchio thread ma la domanda era ancora rilevante almeno per me!


6
Questo è un bel trucco, anche se se passi qualcosa di non valido, il messaggio di errore sarà soloinvalid <lambda> value
Brad Solomon

38

Per gli altri che hanno raggiunto questo obiettivo tramite i motori di ricerca: in Python 3.7, è possibile utilizzare il .fromisoformatmetodo della classe standard invece di reinventare la ruota per date conformi a ISO-8601, ad esempio:

parser.add_argument('-s', "--startdate",
    help="The Start Date - format YYYY-MM-DD",
    required=True,
    type=datetime.date.fromisoformat)
parser.add_argument('-e', "--enddate",
    help="The End Date format YYYY-MM-DD (Inclusive)",
    required=True,
    type=datetime.date.fromisoformat)

5
Inoltre, dateutilil parser ISO di richiede una serie di funzioni aggiuntive che sono ancora conformi allo standard ISO 8601-2004. Puoi usare import dateutil.parser-> type=dateutil.parser.isoparseotype=dateutil.parser.parse
Brad Solomon

@BradSolomon In effetti un buon suggerimento (da qui il mio +1), ma dateutilè un pacchetto di terze parti. Si dovrebbe giudicare i suoi vantaggi rispetto al (piccolo) fastidio di installarlo in più. YMMV.
Laryx Decidua
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.