Giriş argümanları için biçim belirleme argparse python


111

Bazı komut satırı girdileri gerektiren bir python betiğim var ve bunları ayrıştırmak için argparse kullanıyorum. Belgeleri biraz kafa karıştırıcı buldum ve giriş parametrelerinde bir formatı kontrol etmenin bir yolunu bulamadım. Biçimi kontrol etmekle kastettiğim, bu örnek komut dosyasıyla açıklanmaktadır:

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

Seçeneği -sve -ekullanıcı tarafından yapılan girdinin formatta olduğunu kontrol etmem gerekiyor YYYY-MM-DD. Argparse'de bunu hangisinin gerçekleştirdiğini bilmediğim bir seçenek var mı?

Yanıtlar:


235

Başına belgeler :

typeAnahtar kelime argüman add_argument()... gerekli tip denetimi ve tip dönüşümleri uygulanmasına olanak tanıyan type=tek bir dize argümanı ve getiri Dönüştürülen değer alır herhangi çağrılabilir alabilir

Şunun gibi bir şey yapabilirsiniz:

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)

O zaman bunu şu şekilde kullanın type:

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

Düzenlediğiniz diğer soru hakkında bana bunun için dokümantasyona (varsa) yönlendirebilir misiniz?
Sohaib

valid_date()Verilen argümanın bir dizge olduğunu varsayıyor mu ?
Stevoisiak

1
@StevenVascellaro evet, ancak API'nin tanımladığı şey bu; Dokümanlardaki alıntı başına "tek bir dize bağımsız değişkeni alır" .
jonrsharpe

71

Yukarıdaki cevaba eklemek için, tek satırda tutmak istiyorsanız bir lambda işlevi kullanabilirsiniz. Örneğin:

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

Eski konu ama soru en azından benim için hala geçerliydi!


6
Bu güzel bir numara, ancak geçersiz bir şey iletirseniz, hata mesajı şöyle olacaktırinvalid <lambda> value
Brad Solomon

38

Arama motorları aracılığıyla buna .fromisoformatulaşan diğerleri için: Python 3.7'de, tekerleği ISO-8601 uyumlu tarihler için yeniden keşfetmek yerine standart sınıf yöntemini kullanabilirsiniz , örneğin:

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
Buna ek olarak, dateutil'nin ISO ayrıştırıcı hala ISO 8601-2004 uyumlu ek fmts bir dizi sürer. Kullanabilirsiniz import dateutil.parser-> type=dateutil.parser.isoparseveyatype=dateutil.parser.parse
Brad Solomon

@BradSolomon Gerçekten iyi bir öneri (dolayısıyla benim + 1'im), ancak dateutilüçüncü taraf bir pakettir. Ekstra kurulum (küçük) zahmetine karşı faydalarını değerlendirmek gerekir. YMMV.
Laryx Desidua
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.