ระบุรูปแบบสำหรับอาร์กิวเมนต์อินพุตอาร์กิวเมนต์ python


111

ฉันมีสคริปต์ python ที่ต้องการอินพุตบรรทัดคำสั่งและฉันใช้ argparse เพื่อแยกวิเคราะห์พวกเขา ฉันพบว่าเอกสารมีความสับสนเล็กน้อยและไม่พบวิธีตรวจสอบรูปแบบในพารามิเตอร์อินพุต ความหมายของการตรวจสอบรูปแบบอธิบายด้วยสคริปต์ตัวอย่างนี้:

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

ฉันจำเป็นต้องตรวจสอบตัวเลือก-sและว่าการป้อนข้อมูลโดยผู้ใช้ที่อยู่ในรูปแบบ-e YYYY-MM-DDมีตัวเลือกในการโต้แย้งหรือไม่ที่ฉันไม่ทราบว่าสิ่งใดทำได้สำเร็จ

คำตอบ:


236

ตามเอกสารประกอบ :

typeโต้แย้งคำหลักadd_argument()ช่วยให้จำเป็นแปลงชนิดการตรวจสอบและประเภทใดที่จะดำเนินการ ... type=สามารถใช้ callable ใด ๆ ที่จะเกิดการโต้แย้งสายเดียวและผลตอบแทนค่าที่แปลง

คุณสามารถทำสิ่งต่างๆเช่น:

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)

จากนั้นใช้ที่เป็นtype:

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

เกี่ยวกับคำถามอื่น ๆ ที่คุณแก้ไขคุณช่วยชี้ให้ฉันดูเอกสารนั้น (ถ้ามี) ได้ไหม
Sohaib

ไม่valid_date()ถือว่าอาร์กิวเมนต์ที่กำหนดคือสตริงหรือไม่?
Stevoisiak

1
@StevenVascellaro ใช่ แต่นั่นคือสิ่งที่ API กำหนด "ใช้อาร์กิวเมนต์สตริงเดียว"ต่อคำพูดจากเอกสาร
jonrsharpe

71

เพื่อเพิ่มคำตอบข้างต้นคุณสามารถใช้ฟังก์ชันแลมบ์ดาได้หากต้องการเก็บไว้เป็นซับเดียว ตัวอย่างเช่น:

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

กระทู้เก่า แต่คำถามก็ยังคงเกี่ยวข้องสำหรับฉันอย่างน้อย!


6
นี่เป็นเคล็ดลับที่ดีแม้ว่าคุณจะส่งบางสิ่งที่ไม่ถูกต้องข้อความแสดงข้อผิดพลาดก็จะเป็นinvalid <lambda> value
Brad Solomon

38

สำหรับคนอื่น ๆ ที่เข้าถึงสิ่งนี้ผ่านเครื่องมือค้นหา: ใน Python 3.7 คุณสามารถใช้.fromisoformatวิธีการคลาสมาตรฐานแทนการสร้างวงล้อใหม่สำหรับวันที่ที่สอดคล้องกับ ISO-8601 เช่น:

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
นอกจากนี้ตัวแยกวิเคราะห์ ISO dateutilของ ISO ยังใช้ fmts เพิ่มเติมอีกจำนวนหนึ่งซึ่งยังคงเป็นไปตามมาตรฐาน ISO 8601-2004 คุณสามารถใช้import dateutil.parser-> type=dateutil.parser.isoparseหรือtype=dateutil.parser.parse
Brad Solomon

@BradSolomon เป็นคำแนะนำที่ดีจริงๆ (ด้วยเหตุนี้จึง +1 ของฉัน) แต่dateutilเป็นแพ็คเกจของบุคคลที่สาม หนึ่งจะต้องตัดสินประโยชน์ของมันกับความยุ่งยาก (เล็กน้อย) ในการติดตั้งเพิ่มเติม YMMV.
Laryx Decidua
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.