Python argparse mengabaikan argumen yang tidak dikenal

206

Optparse, versi lama mengabaikan semua argumen yang tidak dikenal dan dijalankan. Dalam sebagian besar situasi, ini tidak ideal dan diubah dalam argumen. Tetapi ada beberapa situasi di mana Anda ingin mengabaikan argumen yang tidak dikenal dan menguraikan argumen yang Anda tentukan.

Sebagai contoh:

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

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

Apakah ada cara untuk menimpa ini?

joedborg
sumber
14
Sangat berguna jika Anda menulis pembungkus ke program lain, dan Anda ingin menangkap dan memodifikasi beberapa argumen, tetapi teruskan sisanya!
Alan De Smet
2
Persis mengapa saya berakhir di sini @AlanDeSmet! Senangnya aku tidak mencoba melakukan sesuatu yang gila :)
dwanderson

Jawaban:

351

Menggantikan

args = parser.parse_args()

dengan

args, unknown = parser.parse_known_args()

Sebagai contoh,

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']
unutbu
sumber
21
+1 - tidak tahu ada beberapa hal sepertiparse_known_args
avasal
7
Saya juga tidak! Saya bahkan melewatkannya di docs docs.python.org/library/… . Terima kasih
joedborg
1
Ini muncul ketika mencoba menggunakan nosetest dengan parsearg (ia menolak untuk mengizinkan argumen nosetest digunakan) alasannya adalah karena saya melakukan parser.parse_args(None)daripada parser.parse_args([])dalam tes saya.
Andy Hayden
3
FWIW, menggunakan parse_known_argsdaripada parse_argsmemungkinkan penggunaan ArgumentParserkode dalam lingkup if __name__ == 'main':(kondisi yang berlaku Trueuntuk semua sel dalam Notebook IPython ... yang saya temukan sangat membantu pengembangan dan pengujian kode yang ingin saya migrasikan ke skrip yang dipanggil pada akhirnya) dari baris perintah)
gtion
1
Ini tampaknya tidak bekerja dengan argumen opsional yang "diketahui" tidak disahkan.
Sharud
21

Anda dapat menempatkan bagian yang tersisa ke dalam argumen baru parser.add_argument('args', nargs=argparse.REMAINDER)jika Anda ingin menggunakannya.

lichenbo
sumber
1
Ini berfungsi dengan parse_args()dan tidak memerlukan parse_known_args()(pada Python 2.7).
OozeMeister
4
Menggunakan argparse.REMAINDER tampaknya penuh dengan bug lama. Saya tentu saja tidak bisa membuatnya bekerja. parse_known_args () adalah alternatif yang baik.
Matt
1
Baru saja bertemu bug REMAINDER lama hari ini: bugs.python.org/issue17050
Scott Carpenter
7

Sebenarnya argparse masih "abaikan" _unrecognized_args. Selama argumen "tidak dikenal" ini tidak menggunakan awalan default Anda tidak akan mendengar keluhan dari parser.

Menggunakan konfigurasi @ anutbu tetapi dengan standar parse.parse_args(), jika kami menjalankan program kami dengan argumen berikut.

$ program --foo BAR a b +cd e

Kami akan memiliki pengumpulan data Namespaced ini untuk bekerja dengan.

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

Jika kami ingin awalan default -diabaikan, kami dapat mengubah ArgumentParser dan memutuskan bahwa kami akan menggunakan +untuk argumen "yang dikenali".

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

Perintah yang sama akan menghasilkan

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

Letakkan itu di pipa Anda dan merokok itu =)

nJoy!

nickl-
sumber