Python argparse ละเว้นอาร์กิวเมนต์ที่ไม่รู้จัก


206

optparse เวอร์ชันเก่าจะไม่สนใจอาร์กิวเมนต์ที่ไม่รู้จักทั้งหมดและดำเนินการต่อ ในสถานการณ์ส่วนใหญ่สิ่งนี้ไม่เหมาะและถูกเปลี่ยนเป็นอาร์กิวเมนต์ แต่มีบางสถานการณ์ที่คุณต้องการละเว้นอาร์กิวเมนต์ที่ไม่รู้จักและแยกวิเคราะห์อาร์กิวเมนต์ที่คุณระบุ

ตัวอย่างเช่น:

parser = argparse.ArgumentParser()
parser.add_argument('--foo', dest="foo")
parser.parse_args()

$python myscript.py --foo 1 --bar 2
error: unrecognized arguments: --bar

อย่างไรก็ตามมีการเขียนทับนี้หรือไม่?


14
มีประโยชน์มากถ้าคุณกำลังเขียน wrapper ไปยังโปรแกรมอื่นและคุณต้องการที่จะจับและแก้ไขข้อโต้แย้งเล็กน้อย
Alan De Smet

2
ทำไมฉันถึงลงเอยที่นี่ @AlanDeSmet! ดีใจที่ฉันไม่ได้พยายามที่จะทำสิ่งที่บ้า :)
dwanderson

คำตอบ:


351

แทนที่

args = parser.parse_args()

กับ

args, unknown = parser.parse_known_args()

ตัวอย่างเช่น,

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
args, unknown = parser.parse_known_args(['--foo', 'BAR', 'spam'])
print(args)
# Namespace(foo='BAR')
print(unknown)
# ['spam']

21
+1 - ไม่ทราบว่ามีบางสิ่งเช่นparse_known_args
avasal

7
ฉันก็ไม่! ฉันยังพลาดมันในเอกสารdocs.python.org/library/... ขอบคุณ
joedborg

1
สิ่งนี้เกิดขึ้นเมื่อพยายามใช้ nosetest กับ parseargs (มันปฏิเสธที่จะอนุญาตให้ใช้ nosetest args) เหตุผลก็เพราะฉันทำparser.parse_args(None)มากกว่าparser.parse_args([])การทดสอบ
Andy Hayden

3
FWIW การใช้parse_known_argsแทนที่จะparse_argsเปิดใช้งานการใช้ArgumentParserโค้ดในขอบเขตของif __name__ == 'main':(เงื่อนไขที่มีTrueไว้สำหรับเซลล์ทั้งหมดในโน๊ตบุ๊ค IPython ... ซึ่งฉันพบว่าช่วยในการพัฒนาและทดสอบโค้ดที่ฉันต้องการโยกย้ายไปยังสคริปต์ที่เรียกใช้ในที่สุด จากบรรทัดคำสั่ง)
ริเริ่ม

1
ดูเหมือนจะไม่ทำงานกับตัวเลือก args ที่เป็น "รู้จัก" ไม่ถูกส่งเข้า
Sharud

21

คุณสามารถใส่ส่วนที่เหลือลงในอาร์กิวเมนต์ใหม่ด้วยparser.add_argument('args', nargs=argparse.REMAINDER)ถ้าคุณต้องการใช้พวกเขา


1
สิ่งนี้ใช้ได้กับparse_args()และไม่จำเป็นต้องใช้parse_known_args()(ใน Python 2.7)
OozeMeister

4
การใช้ argparse.REMAINDER นั้นดูเหมือนจะเต็มไปด้วยข้อบกพร่องอันยาวนาน แน่นอนฉันไม่สามารถทำงานได้ parse_known_args () เป็นทางเลือกที่ดี
Matt

1
เพิ่งพบข้อผิดพลาดของ REMAINDER ที่ยาวนานมานานแล้ววันนี้: bugs.python.org/issue17050
Scott Carpenter

7

อันที่จริงไม่ argparse ยัง _unrecognized_args"ละเว้น" ตราบใดที่ข้อโต้แย้ง "ไม่รู้จัก" เหล่านี้ไม่ใช้คำนำหน้าเริ่มต้นคุณจะไม่ได้ยินคำร้องเรียนจากตัวแยกวิเคราะห์

ใช้การกำหนดค่าของ @ anutbu แต่ใช้กับมาตรฐานparse.parse_args()หากเราต้องดำเนินการโปรแกรมด้วยอาร์กิวเมนต์ดังต่อไปนี้

$ program --foo BAR a b +cd e

เราจะมีการรวบรวมข้อมูล Namespaced นี้เพื่อทำงานกับ

Namespace(_unrecognized_args=['a', 'b', '+cd', 'e'], foo='BAR')

ถ้าเราต้องการให้ส่วนนำหน้าเริ่มต้น-ถูกเพิกเฉยเราสามารถเปลี่ยน ArgumentParser และตัดสินใจว่าเราจะใช้+อาร์กิวเมนต์สำหรับ "รู้จัก" แทน

parser = argparse.ArgumentParser(prefix_chars='+')
parser.add_argument('+cd')

คำสั่งเดียวกันจะผลิต

Namespace(_unrecognized_args=['--foo', 'BAR', 'a', 'b'], cd='e')

ใส่ในท่อของคุณและสูบมัน =)

Njoy!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.