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?

Sohaib
quelle

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)
Jonrsharpe
quelle
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!

Evan V.
quelle
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)
Michał Górny
quelle
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