Argparse do Python ignora argumentos não reconhecidos

206

Além disso, a versão antiga ignora todos os argumentos não reconhecidos e continua. Na maioria das situações, isso não é o ideal e foi alterado em argparse. Mas há algumas situações em que você deseja ignorar qualquer argumento não reconhecido e analisar os que você especificou.

Por exemplo:

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

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

Existe alguma maneira de substituir isso?

joedborg
fonte
14
Muito útil se você estiver gravando um wrapper em outro programa e desejar capturar e modificar alguns argumentos, mas repasse o restante!
Alan De Smet
2
Exatamente por que acabei aqui @AlanDeSmet! Ainda bem que eu não estou tentando fazer algo louco :)
dwanderson

Respostas:

351

Substituir

args = parser.parse_args()

com

args, unknown = parser.parse_known_args()

Por exemplo,

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
fonte
21
+1 - não sabia que havia algo comoparse_known_args
avasal 10/10/12
7
Nem eu fiz! Eu até senti falta na documentação docs.python.org/library/… . Graças
joedborg
1
Isso surgiu ao tentar usar nosetest com parseargs (recusou-se a permitir o uso de argumentos nosetest), o motivo foi porque eu estava fazendo parser.parse_args(None)mais do que parser.parse_args([])nos meus testes.
Andy Hayden
3
FWIW, usar em parse_known_argsvez de permitir parse_argso uso de ArgumentParsercódigo dentro do escopo de if __name__ == 'main':(uma condição que é Truepara todas as células em um Notebook IPython ... que eu acho que ajuda muito no código de desenvolvimento e teste que eu quero migrar para um script chamado a partir de uma linha de comando)
bom senso 28/01
1
Isso não parece funcionar com argumentos opcionais que são "conhecidos" não sendo passados.
Sharud
21

Você pode colocar as partes restantes em um novo argumento parser.add_argument('args', nargs=argparse.REMAINDER)se quiser usá-las.

líquen
fonte
1
Isso funciona com parse_args()e não requer parse_known_args()(no Python 2.7).
OozeMeister
4
O uso do argparse.REMAINDER parece estar repleto de erros de longa data. Certamente não consigo fazê-lo funcionar. parse_known_args () é uma boa alternativa.
Matt
1
Acabei de encontrar um bug REMAINDER de
Scott Carpenter
7

Na verdade, o argparse ainda "ignora" _unrecognized_args. Contanto que esses argumentos "não reconhecidos" não usem o prefixo padrão, você não ouvirá reclamações do analisador.

Usando a configuração do @ anutbu, mas com o padrão parse.parse_args(), se executássemos nosso programa com os seguintes argumentos.

$ program --foo BAR a b +cd e

Teremos essa coleta de dados com espaço para nome para trabalhar.

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

Se quiséssemos -ignorar o prefixo padrão , poderíamos alterar o ArgumentParser e decidir que usaríamos um +para nossos argumentos "reconhecidos".

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

O mesmo comando produzirá

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

Coloque isso no seu cachimbo e fume =)

nJoy!

nickl-
fonte