Geben Sie das Format für die Eingabeargumente argparse python an


111

Ich habe ein Python-Skript, das einige Befehlszeileneingaben erfordert, und ich verwende argparse, um sie zu analysieren. Ich fand die Dokumentation etwas verwirrend und konnte keine Möglichkeit finden, in den Eingabeparametern nach einem Format zu suchen. Was ich unter Überprüfen des Formats verstehe, wird anhand dieses Beispielskripts erklärt:

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__)))

Ich muss nach Optionen suchen -sund sicherstellen, -edass die Eingabe des Benutzers im Format vorliegt YYYY-MM-DD. Gibt es eine Option in Argparse, von der ich nicht weiß, welche dies bewirkt?

Antworten:


235

Gemäß der Dokumentation :

Mit dem typeSchlüsselwortargument von add_argument()können alle erforderlichen Typprüfungen und Typkonvertierungen durchgeführt werden. Sie type=können alle aufrufbaren Elemente verwenden, die ein einzelnes Zeichenfolgenargument verwenden und den konvertierten Wert zurückgeben

Sie könnten so etwas tun wie:

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)

Dann benutze das als type:

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

Können Sie mich zu der anderen Frage, die Sie bearbeitet haben, auf die Dokumentation (falls vorhanden) verweisen?
Sohaib

Nimmt valid_date()das angegebene Argument eine Zeichenfolge an?
Stevoisiak

1
@StevenVascellaro ja, aber das definiert die API; "Nimmt ein einzelnes Zeichenfolgenargument" gemäß dem Zitat aus den Dokumenten.
Jonrsharpe

71

Um die obige Antwort zu ergänzen, können Sie eine Lambda-Funktion verwenden, wenn Sie sie auf einem Einzeiler belassen möchten. Beispielsweise:

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

Alter Thread, aber die Frage war zumindest für mich noch relevant!


6
Dies ist ein netter Trick, obwohl, wenn Sie etwas ungültiges übergeben, die Fehlermeldung nur sein wirdinvalid <lambda> value
Brad Solomon

38

Für andere, die dies über Suchmaschinen erreichen: In Python 3.7 können Sie die Standardklassenmethode .fromisoformatverwenden, anstatt das Rad für ISO-8601-konforme Daten neu zu erfinden, z.

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
Darüber hinaus benötigt dateutilder ISO-Parser eine Reihe zusätzlicher FMTS, die noch ISO 8601-2004-konform sind. Sie können import dateutil.parser-> type=dateutil.parser.isoparseodertype=dateutil.parser.parse
Brad Solomon

@BradSolomon Ein guter Vorschlag (daher meine +1), aber dateutilein Paket von Drittanbietern. Man müsste seine Vorteile anhand des (kleinen) Aufwandes bei der zusätzlichen Installation beurteilen. YMMV.
Laryx Decidua
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.