Python argparse игнорирует нераспознанные аргументы

206

Optparse, старая версия просто игнорирует все нераспознанные аргументы и продолжает. В большинстве случаев это не идеально и было изменено в argparse. Но есть несколько ситуаций, когда вы хотите игнорировать нераспознанные аргументы и анализировать те, которые вы указали.

Например:

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

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

Есть ли способ перезаписать это?

joedborg
источник
14
Очень удобно, если вы пишете обертку для другой программы и хотите захватить и изменить несколько аргументов, а остальные передать!
Алан Де Смет
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']
unutbu
источник
21
+1 - не знал, что есть что-то вродеparse_known_args
avasal
7
И я тоже! Я даже пропустил это в docs docs.python.org/library/… . Спасибо
joedborg
1
Это возникло при попытке использовать тестирование носа с парсерами (оно не позволяло использовать аргументы для проверки носа), причина была в том, что я делал это, parser.parse_args(None)а не parser.parse_args([])в своих тестах.
Энди Хейден
3
FWIW, использующий, parse_known_argsа не parse_argsразрешающий использование ArgumentParserв коде в рамках if __name__ == 'main':(условие, которое относится Trueко всем ячейкам в записной книжке IPython ... которое, как я нахожу, очень помогает при разработке и тестировании кода, который я хочу со временем перенести в вызываемый скрипт из командной строки)
gumption
1
Похоже, что это не работает с необязательными аргументами, которые «известны» не передаются.
Шаруд,
21

Вы можете поместить оставшиеся части в новый аргумент, parser.add_argument('args', nargs=argparse.REMAINDER)если хотите использовать их.

lichenbo
источник
1
Это работает с parse_args()и не требует parse_known_args()(на Python 2.7).
OozeMeister
4
Использование argparse.REMAINDER кажется чреватым давними ошибками. Я, конечно, не могу заставить его работать. parse_known_args () - хорошая альтернатива.
Мэтт
1
Просто столкнулся с давней ошибкой REMAINDER
Скотт Карпентер
7

На самом деле argparse все еще «игнорирует» _unrecognized_args. Пока эти «нераспознанные» аргументы не используют префикс по умолчанию, вы не услышите жалоб от парсера.

Использование конфигурации @ anutbu, но со стандартом parse.parse_args(), если бы мы выполняли нашу программу со следующими аргументами.

$ program --foo BAR a b +cd e

У нас будет этот сбор данных в пространстве имен для работы.

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!

nickl-
источник