optparse
— Analisador sintático para opções de linha de comando¶
Código-fonte: Lib/optparse.py
Obsoleto desde a versão 3.2: O módulo optparse
está suavemente descontinuado e não será mais desenvolvido; o desenvolvimento continuará com o módulo argparse
.
optparse
é uma biblioteca mais conveniente, flexível e poderosa para analisar opções de linha de comando do que o antigo módulo getopt
. optparse
usa um estilo mais declarativo de análise de linha de comando: você cria uma instância de OptionParser
, preenche-a com opções e analisa a linha de comando. optparse
permite que os usuários especifiquem opções na sintaxe convencional GNU/POSIX e, adicionalmente, gera mensagens de uso e ajuda para você.
Aqui está um exemplo de uso de optparse
em um script simples:
from optparse import OptionParser
...
parser = OptionParser()
parser.add_option("-f", "--file", dest="filename",
help="write report to FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose", default=True,
help="don't print status messages to stdout")
(options, args) = parser.parse_args()
Com essas poucas linhas de código, os usuários do seu script agora podem fazer “coisas comuns” na linha de comando, por exemplo:
<seuscript> --file=outfile -q
Ao analisar a linha de comando, optparse
define atributos do objeto options
retornado por parse_args()
com base nos valores de linha de comando fornecidos pelo usuário. Quando parse_args()
retorna da análise desta linha de comando, options.filename
será "outfile"
e options.verbose
será False
. optparse
provê as opções longas e curtas, permite que opções curtas sejam mescladas e permite que opções sejam associadas a seus argumentos de várias maneiras. Portanto, as seguintes linhas de comando são todas equivalentes ao exemplo acima:
<seuscript> -f outfile --quiet
<seuscript> --quiet --file outfile
<seuscript> -q -foutfile
<seuscript> -qfoutfile
Além disso, os usuários podem executar um dos seguintes:
<seuscript> -h
<seuscript> --help
e optparse
vai exibir um breve resumo das opções do seu script:
Usage: <seuscript> [options]
Options:
-h, --help show this help message and exit
-f FILE, --file=FILE write report to FILE
-q, --quiet don't print status messages to stdout
onde o valor de seuscript é determinado em tempo de execução (normalmente de sys.argv[0]
).
Contexto¶
optparse
foi explicitamente projetado para encorajar a criação de programas com interfaces de linha de comando diretas e convencionais. Para esse fim, ele provê apenas a sintaxe e a semântica de linha de comando mais comuns convencionalmente usadas no Unix. Se você não estiver familiarizado com essas convenções, leia esta seção para se familiarizar com elas.
Terminologia¶
- argumento
uma string inserida na linha de comando e passada pelo shell para
execl()
ouexecv()
. Em Python, argumentos são elementos desys.argv[1:]
(sys.argv[0]
é o nome do programa que está sendo executado). Shells Unix também usam o termo “word”.Ocasionalmente, é desejável substituir uma lista de argumentos diferente de
sys.argv[1:]
, então você deve ler “argumento” como “um elemento desys.argv[1:]
, ou de alguma outra lista fornecida como um substituto parasys.argv[1:]
”.- opção
um argumento usado para fornecer informações extras para guiar ou personalizar a execução de um programa. Existem muitas sintaxes diferentes para opções; a sintaxe tradicional do Unix é um hífen (“-”) seguido por uma única letra, por exemplo,
-x
ou-F
. Além disso, a sintaxe tradicional do Unix permite que várias opções sejam mescladas em um único argumento, por exemplo,-x -F
é equivalente a-xF
. O projeto GNU introduziu--
seguido por uma série de palavras separadas por hífen, por exemplo,--file
ou--dry-run
. Essas são as únicas duas sintaxes de opção fornecidas poroptparse
.Algumas outras sintaxes de opções que o mundo viu incluem:
um hífen seguido por algumas letras, por exemplo
-pf
(isso não é o mesmo que várias opções mescladas em um único argumento)um hífen seguido por uma palavra completa, por exemplo
-file
(isso é tecnicamente equivalente à sintaxe anterior, mas eles geralmente não são vistos no mesmo programa)um sinal de mais seguido por uma única letra, ou algumas letras, ou uma palavra, por exemplo
+f
,+rgb
uma barra seguida de uma letra, ou algumas letras, ou uma palavra, por exemplo
/f
,/file
Essas sintaxes de opção não são suportadas por
optparse
, e nunca serão. Isso é proposital: as três primeiras não são padrão em nenhum ambiente, e a última só faz sentido se você estiver mirando exclusivamente no Windows ou em certas plataformas legadas (por exemplo, VMS, MS-DOS).- argumento de opção
um argumento que segue uma opção, está intimamente associado a essa opção e é consumido da lista de argumentos quando essa opção é. Com
optparse
, os argumentos de opção podem estar em um argumento separado de sua opção:-f foo --file foo
ou incluídos no mesmo argumento:
-ffoo --file=foo
Normalmente, uma opção dada ou aceita um argumento ou não. Muitas pessoas querem um recurso de “argumentos opcionais de opção”, o que significa que algumas opções aceitarão um argumento se o virem, e não aceitarão se não o virem. Isso é um tanto controverso, porque torna a análise ambígua: se
-a
aceita um argumento opcional e-b
é outra opção inteiramente diferente, como interpretamos-ab
? Por causa dessa ambiguidade,optparse
não provê esse recurso.- argumento posicional
algo que sobrou na lista de argumentos depois que as opções foram analisadas, ou seja, depois que as opções e seus argumentos foram analisados e removidos da lista de argumentos.
- opção obrigatória
uma opção que deve ser fornecida na linha de comando; observe que a frase “opção obrigatória” é autocontraditória em inglês.
optparse
não impede que você implemente opções obrigatórias, mas também não ajuda muito nisso.
Por exemplo, considere esta linha de comando hipotética:
prog -v --report report.txt foo bar
-v
e --report
são ambas opções. Supondo que --report
receba um argumento, report.txt
é um argumento de opção. foo
e bar
são argumentos posicionais.
Para que servem as opções?¶
As opções são usadas para fornecer informações extras para ajustar ou personalizar a execução de um programa. Caso não tenha ficado claro, as opções geralmente são opcionais. Um programa deve ser capaz de executar muito bem sem nenhuma opção. (Escolha um programa aleatório dos conjuntos de ferramentas Unix ou GNU. Ele pode ser executado sem nenhuma opção e ainda fazer sentido? As principais exceções são find
, tar
e dd
— todos eles são mutantes excêntricos que foram corretamente criticados por sua sintaxe não padrão e interfaces confusas.)
Muitas pessoas querem que seus programas tenham “opções obrigatórias”. Pense nisso. Se é obrigatório, então não é opcional! Se há uma informação que seu programa absolutamente requer para ser executado com sucesso, é para isso que servem os argumentos posicionais.
Como um exemplo de bom design de interface de linha de comando, considere o humilde utilitário cp
, para copiar arquivos. Não faz muito sentido tentar copiar arquivos sem fornecer um destino e pelo menos uma fonte. Portanto, cp
falha se você executá-lo sem argumentos. No entanto, ele tem uma sintaxe flexível e útil que não requer nenhuma opção:
cp ORIGEM DESTINO
cp ORIGEM ... DIRETÓRIO
Você pode ir bem longe só com isso. A maioria das implementações de cp
fornece um monte de opções para ajustar exatamente como os arquivos são copiados: você pode preservar o modo e o tempo de modificação, evitar seguir links simbólicos, perguntar antes de destruir arquivos existentes, etc. Mas nada disso distrai da missão principal de cp
, que é copiar um arquivo para outro, ou vários arquivos para outro diretório.
Para que servem os argumentos posicionais?¶
Argumentos posicionais são para aquelas informações que seu programa absolutamente e positivamente requer para ser executado.
Uma boa interface de usuário deve ter o mínimo de requisitos absolutos possível. Se seu programa requer 17 informações distintas para ser executado com sucesso, não importa muito como você obtém essas informações do usuário — a maioria das pessoas desistirá e irá embora antes de executar o programa com sucesso. Isso se aplica se a interface de usuário for uma linha de comando, um arquivo de configuração ou uma GUI: se você fizer tantas exigências aos seus usuários, a maioria deles simplesmente desistirá.
Em resumo, tente minimizar a quantidade de informações que os usuários são absolutamente obrigados a fornecer — use padrões sensatos sempre que possível. Claro, você também quer tornar seus programas razoavelmente flexíveis. É para isso que servem as opções. Novamente, não importa se são entradas em um arquivo de configuração, widgets no diálogo “Preferências” de uma GUI ou opções de linha de comando — quanto mais opções você implementar, mais flexível será seu programa e mais complicada se tornará sua implementação. Muita flexibilidade também tem desvantagens, é claro; muitas opções podem sobrecarregar os usuários e tornar seu código muito mais difícil de manter.
Tutorial¶
Embora optparse
seja bastante flexível e poderoso, ele também é simples de usar na maioria dos casos. Esta seção abrange os padrões de código que são comuns a qualquer programa baseado em optparse
.
Primeiro, você precisa importar a classe OptionParser; então, no início do programa principal, crie uma instância de OptionParser:
from optparse import OptionParser
...
parser = OptionParser()
Então você pode começar a definir opções. A sintaxe básica é:
parser.add_option(opt_str, ...,
attr=value, ...)
Cada opção tem uma ou mais strings de opção, como -f
ou --file
, e vários atributos de opção que informam ao optparse
o que esperar e o que fazer quando encontrar essa opção na linha de comando.
Normalmente, cada opção terá uma sequência de opções curta e uma sequência de opções longa, por exemplo:
parser.add_option("-f", "--file", ...)
Você tem a liberdade de definir quantas strings de opções curtas e longas quiser (incluindo zero), desde que haja pelo menos uma string de opção no geral.
As strings de opção passadas para OptionParser.add_option()
são efetivamente rótulos para a opção definida por essa chamada. Para resumir, frequentemente nos referiremos a encontrar uma opção na linha de comando; na realidade, optparse
encontra strings de opção e procura opções a partir delas.
Depois que todas as suas opções estiverem definidas, instrua optparse
para analisar a linha de comando do seu programa:
(options, args) = parser.parse_args()
(Se desejar, você pode passar uma lista de argumentos personalizada para parse_args()
, mas isso raramente é necessário: por padrão, ele usa sys.argv[1:]
.)
parse_args()
retorna dois valores:
options
, um objeto que contém valores para todas as suas opções — por exemplo, se--file
receber um único argumento de string, entãooptions.file
será o nome do arquivo fornecido pelo usuário, ouNone
se o usuário não forneceu essa opçãoargs
, a lista de argumentos posicionais restantes após a análise de opções
Esta seção do tutorial abrange apenas os quatro atributos de opção mais importantes: action
, type
, dest
(destino) e help
. Destes, action
é o mais fundamental.
Compreendendo as ações de opções¶
Ações dizem ao optparse
o que fazer quando ele encontra uma opção na linha de comando. Há um conjunto fixo de ações codificadas em optparse
; adicionar novas ações é um tópico avançado abordado na seção Estendendo optparse. A maioria das ações diz ao optparse
para armazenar um valor em alguma variável — por exemplo, pegue uma string da linha de comando e armazene-a em um atributo de options
.
Se você não especificar uma ação de opção, optparse
assumirá como padrão store
.
A ação store¶
A ação de opção mais comum é store
, que diz ao optparse
para pegar o próximo argumento (ou o restante do argumento atual), garantir que seja do tipo correto e armazená-lo no destino escolhido.
Por exemplo:
parser.add_option("-f", "--file",
action="store", type="string", dest="filename")
Agora vamos criar uma linha de comando falsa e pedir ao optparse
para analisá-la:
args = ["-f", "foo.txt"]
(options, args) = parser.parse_args(args)
Quando optparse
vê a string de opção -f
, ele consome o próximo argumento, foo.txt
, e o armazena em options.filename
. Então, após essa chamada para parse_args()
, options.filename
é "foo.txt"
.
Alguns outros tipos de opção suportados por optparse
são int
e float
. Aqui está uma opção que espera um argumento inteiro:
parser.add_option("-n", type="int", dest="num")
Note que esta opção não tem uma string de opção longa, o que é perfeitamente aceitável. Além disso, não há nenhuma ação explícita, já que o padrão é store
.
Vamos analisar outra linha de comando falsa. Desta vez, vamos colocar o argumento de opção bem perto da opção: já que -n42
(um argumento) equivale a -n 42
(dois argumentos), o código
(options, args) = parser.parse_args(["-n42"])
print(options.num)
vai exibir 42
.
Se você não especificar um tipo, optparse
presume string
. Combinado com o fato de que a ação padrão é store
, isso significa que nosso primeiro exemplo pode ser muito mais curto:
parser.add_option("-f", "--file", dest="filename")
Se você não fornecer um destino, optparse
descobre um padrão sensato a partir das strings de opção: se a primeira string de opção longa for --foo-bar
, então o destino padrão é foo_bar
. Se não houver strings de opção longas, optparse
olha para a primeira string de opção curta: o destino padrão para -f
é f
.
optparse
também inclui o tipo complex
embutido. Adicionar tipos é abordado na seção Estendendo optparse.
Manipulando opções (sinalizadores) booleanas¶
Opções de sinalizador — define uma variável como true ou false quando uma opção específica é vista — são bem comuns. optparse
suporta-as com duas ações separadas, store_true
e store_false
. Por exemplo, você pode ter um sinalizador verbose
que é ativado com -v
e desativado com -q
:
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")
Aqui temos duas opções diferentes com o mesmo destino, o que é perfeitamente OK. (Isso significa apenas que você tem que ter um pouco de cuidado ao definir valores padrão — veja abaixo.)
Quando optparse
encontra -v
na linha de comando, ele define options.verbose
como True
; quando encontra -q
, options.verbose
é definido como False
.
Outras ações¶
Algumas outras ações suportadas por optparse
são:
"store_const"
armazena um valor constante, predefinido via
Option.const
"append"
anexa o argumento desta opção a uma lista
"count"
incrementa um contador em um
"callback"
chama uma função especificada
Elas são abordadas na seção Guia de referência e na seção Funções de retorno de opção.
Valores padrão¶
Todos os exemplos acima envolvem a configuração de alguma variável (o “destino”) quando certas opções de linha de comando são vistas. O que acontece se essas opções nunca forem vistas? Como não fornecemos nenhum padrão, todas elas são definidas como None
. Isso geralmente é bom, mas às vezes você quer mais controle. optparse
permite que você forneça um valor padrão para cada destino, que é atribuído antes da análise da linha de comando.
Primeiro, considere o exemplo de verbose/quiet. Se quisermos que optparse
defina verbose
como True
a menos que -q
seja visto, então podemos fazer isso:
parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")
Como os valores padrão se aplicam ao destino e não a qualquer opção específica, e essas duas opções têm o mesmo destino, isso é exatamente equivalente:
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)
Considere isso:
parser.add_option("-v", action="store_true", dest="verbose", default=False)
parser.add_option("-q", action="store_false", dest="verbose", default=True)
Novamente, o valor padrão para verbose
será True
: o último valor padrão fornecido para qualquer destino específico é o que conta.
Uma maneira mais clara de especificar valores padrão é o método set_defaults()
do OptionParser, que você pode chamar a qualquer momento antes de chamar parse_args()
:
parser.set_defaults(verbose=True)
parser.add_option(...)
(options, args) = parser.parse_args()
Como antes, o último valor especificado para um destino de opção dado é o que conta. Para maior clareza, tente usar um método ou outro de configuração de valores padrão, não ambos.
Gerando texto de ajuda¶
A capacidade do optparse
de gerar texto de ajuda e uso automaticamente é útil para criar interfaces de linha de comando amigáveis ao usuário. Tudo o que você precisa fazer é fornecer um valor help
para cada opção e, opcionalmente, uma curta mensagem de uso para todo o seu programa. Aqui está um OptionParser preenchido com opções amigáveis (documentadas) ao usuário:
usage = "usage: %prog [options] arg1 arg2"
parser = OptionParser(usage=usage)
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=True,
help="make lots of noise [default]")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose",
help="be vewwy quiet (I'm hunting wabbits)")
parser.add_option("-f", "--filename",
metavar="FILE", help="write output to FILE")
parser.add_option("-m", "--mode",
default="intermediate",
help="interaction mode: novice, intermediate, "
"or expert [default: %default]")
Se optparse
encontrar -h
ou --help
na linha de comando, ou se você apenas chamar parser.print_help()
, ele exibe o seguinte na saída padrão:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or
expert [default: intermediate]
(Se a saída de ajuda for acionada por uma opção de ajuda, optparse
sai após imprimir o texto de ajuda.)
Há muita coisa acontecendo aqui para ajudar optparse
a gerar a melhor mensagem de ajuda possível:
o script define sua própria mensagem de uso:
usage = "usage: %prog [options] arg1 arg2"
optparse
expande%prog
na string de uso para o nome do programa atual, ou seja,os.path.basename(sys.argv[0])
. A string expandida é então exibida antes da ajuda detalhada da opção.Se você não fornecer uma string de uso,
optparse
usa um padrão simples, mas sensato:"Usage: %prog [options]"
, o que é bom se seu script não aceita nenhum argumento posicional.cada opção define uma string de ajuda e não se preocupa com quebra de linha —
optparse
cuida da quebra de linhas e faz com que a saída de ajuda tenha uma boa aparência.opções que assumem um valor indicam esse fato em sua mensagem de ajuda gerada automaticamente, por exemplo, para a opção “mode”:
-m MODE, --mode=MODE
Aqui, “MODE” é chamado de metavariável: ele representa o argumento que o usuário deve fornecer para
-m
/--mode
. Por padrão,optparse
converte o nome da variável de destino para maiúsculas e usa isso para a metavariável. Às vezes, não é isso que você quer — por exemplo, a opção--filename
define explicitamentemetavar="FILE"
, resultando nesta descrição de opção gerada automaticamente:-f FILE, --filename=FILE
Isso é importante para mais do que apenas economizar espaço: o texto de ajuda escrito manualmente usa a metavariável
FILE
para dar uma pista ao usuário de que há uma conexão entre a sintaxe semiformal-f FILE
e a descrição semântica informal como, por exemplo, “write output to FILE”. Essa é uma maneira simples, mas eficaz, de tornar seu texto de ajuda muito mais claro e útil para usuários finais.opções que têm um valor padrão podem incluir
%default
na string de ajuda —optparse
vai substituí-lo porstr()
do valor padrão da opção. Se uma opção não tiver um valor padrão (ou o valor padrão forNone
),%default
expande paranone
.
Agrupando opções¶
Ao lidar com muitas opções, é conveniente agrupar essas opções para melhor saída de ajuda. Um OptionParser
pode conter vários grupos de opções, cada um dos quais pode conter várias opções.
Um grupo de opções é obtido usando a classe OptionGroup
:
- class optparse.OptionGroup(parser, title, description=None)¶
onde
parser é a instância
OptionParser
na qual o grupo será inseridotitle é o título do grupo
description, opcional, é uma descrição longa do grupo
OptionGroup
herda de OptionContainer
(como OptionParser
) e, portanto, o método add_option()
pode ser usado para adicionar uma opção ao grupo.
Depois que todas as opções são declaradas, usando o método OptionParser
add_option_group()
o grupo é adicionado ao analisador definido anteriormente.
Continuando com o analisador definido na seção anterior, adicionar um OptionGroup
a um analisador é fácil:
group = OptionGroup(parser, "Dangerous Options",
"Caution: use these options at your own risk. "
"It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)
Isso resultaria na seguinte saída de texto de ajuda:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or
expert [default: intermediate]
Dangerous Options:
Caution: use these options at your own risk. It is believed that some
of them bite.
-g Group option.
Um exemplo um pouco mais completo pode envolver o uso de mais de um grupo: ainda estendendo o exemplo anterior:
group = OptionGroup(parser, "Dangerous Options",
"Caution: use these options at your own risk. "
"It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)
group = OptionGroup(parser, "Debug Options")
group.add_option("-d", "--debug", action="store_true",
help="Print debug information")
group.add_option("-s", "--sql", action="store_true",
help="Print all SQL statements executed")
group.add_option("-e", action="store_true", help="Print every action done")
parser.add_option_group(group)
que resulta na seguinte saída:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or expert
[default: intermediate]
Dangerous Options:
Caution: use these options at your own risk. It is believed that some
of them bite.
-g Group option.
Debug Options:
-d, --debug Print debug information
-s, --sql Print all SQL statements executed
-e Print every action done
Outro método interessante, especialmente ao trabalhar programaticamente com grupos de opções, é:
- OptionParser.get_option_group(opt_str)¶
Retorna o objeto
OptionGroup
ao qual a string de opção curta ou longa opt_str (por exemplo,'-o'
ou'--option'
) pertence. Se não houver talOptionGroup
, retornaNone
.
Exibindo uma string de versão¶
Similar à string breve de uso, optparse
também pode exibir uma string de versão para seu programa. Você tem que fornecer a string como o argumento version
para OptionParser:
parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")
%prog
é expandido assim como em usage
. Além disso, version
pode conter qualquer coisa que você quiser. Quando você o fornece, optparse
adiciona automaticamente uma opção --version
ao seu analisador. Se ele encontrar essa opção na linha de comando, ele expande sua string version
(substituindo %prog
), exibindo-a no stdout e sai.
Por exemplo, se o seu script for chamado /usr/bin/foo
:
$ /usr/bin/foo --version
foo 1.0
Os dois métodos a seguir podem ser usados para exibir e obter a string version
:
- OptionParser.print_version(file=None)¶
Exibe a mensagem de versão para o programa atual (
self.version
) em file (stdout padrão). Assim como emprint_usage()
, qualquer ocorrência de%prog
emself.version
é substituída pelo nome do programa atual. Não faz nada seself.version
estiver vazio ou indefinido.
- OptionParser.get_version()¶
O mesmo que
print_version()
, mas retorna a string da versão em vez de exibi-la.
Como optparse
trata erros¶
Existem duas classes amplas de erros com os quais optparse
precisa se preocupar: erros do programador e erros do usuário. Erros do programador geralmente são chamadas errôneas para OptionParser.add_option()
, por exemplo, strings de opção inválidas, atributos de opção desconhecidos, atributos de opção ausentes, etc. Eles são tratados da maneira usual: levanta uma exceção (seja optparse.OptionError
ou TypeError
) e deixe o programa travar.
Lidar com erros do usuário é muito mais importante, pois eles certamente acontecerão não importa quão estável seu código seja. optparse
pode detectar automaticamente alguns erros do usuário, como argumentos de opção ruins (passando -n 4x
onde -n
recebe um argumento inteiro), argumentos ausentes (-n
no final da linha de comando, onde -n
recebe um argumento de qualquer tipo). Além disso, você pode chamar OptionParser.error()
para sinalizar uma condição de erro definida pelo aplicativo:
(options, args) = parser.parse_args()
...
if options.a and options.b:
parser.error("options -a and -b are mutually exclusive")
Em ambos os casos, optparse
lida com o erro da mesma maneira: ele imprime a mensagem de uso do programa e uma mensagem de erro no erro padrão e sai com o status de erro 2.
Considere o primeiro exemplo acima, onde o usuário passa 4x
para uma opção que aceita um inteiro:
$ /usr/bin/foo -n 4x
Usage: foo [options]
foo: error: option -n: invalid integer value: '4x'
Ou, quando o usuário não passa nenhum valor:
$ /usr/bin/foo -n
Usage: foo [options]
foo: error: -n option requires an argument
As mensagens de erro geradas pelo optparse
tomam o cuidado de sempre mencionar a opção envolvida no erro; certifique-se de fazer o mesmo ao chamar OptionParser.error()
do código do sua aplicação.
Se o comportamento padrão de tratamento de erros do optparse
não atender às suas necessidades, você precisará criar uma subclasse de OptionParser e substituir seus métodos exit()
e/ou error()
.
Juntando tudo¶
Veja como os scripts baseados no optparse
geralmente se parecem:
from optparse import OptionParser
...
def main():
usage = "usage: %prog [options] arg"
parser = OptionParser(usage)
parser.add_option("-f", "--file", dest="filename",
help="read data from FILENAME")
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose")
...
(options, args) = parser.parse_args()
if len(args) != 1:
parser.error("incorrect number of arguments")
if options.verbose:
print("reading %s..." % options.filename)
...
if __name__ == "__main__":
main()
Guia de referência¶
Criando o analisador sintático¶
O primeiro passo para usar o optparse
é criar uma instância de OptionParser.
- class optparse.OptionParser(...)¶
O construtor do OptionParser não tem argumentos obrigatórios, mas vários argumentos nomeados opcionais. Você deve sempre passá-los como argumentos nomeados, ou seja, não confie na ordem em que os argumentos são declarados.
usage
(padrão:"%prog [options]"
)O resumo de uso para exibir quando seu programa é executado incorretamente ou com uma opção de ajuda. Quando
optparse
exibe a string de uso, ele expande%prog
paraos.path.basename(sys.argv[0])
(ou paraprog
se você passou esse argumento nomeado). Para suprimir uma mensagem de uso, passe o valor especialoptparse.SUPPRESS_USAGE
.option_list
(padrão:[]
)Uma lista de objetos Option para preencher o analisador sintático. As opções em
option_list
são adicionadas após quaisquer opções emstandard_option_list
(um atributo de classe que pode ser definido por subclasses de OptionParser), mas antes de quaisquer opções de versão ou ajuda. Descontinuado; useadd_option()
após criar o analisador sintático.option_class
(padrão: optparse.Option)Classe para usar ao adicionar opções ao analisador sintático em
add_option()
.version
(padrão:None
)Uma string de versão para exibir quando o usuário fornece uma opção de versão. Se você fornecer um valor true para
version
,optparse
adiciona automaticamente uma opção de versão com a string de opção única--version
. A substring%prog
é expandida da mesma forma que parausage
.conflict_handler
(padrão:"error"
)Especifica o que fazer quando opções com strings de opções conflitantes são adicionadas ao analisador sintático; consulte a seção Conflitos entre opções.
description
(padrão:None
)Um parágrafo de texto que fornece uma breve visão geral do seu programa.
optparse
reformata este parágrafo para ajustá-lo à largura atual do terminal e o exibe quando o usuário solicita ajuda (depois deusage
, mas antes da lista de opções).formatter
(padrão: um novoIndentedHelpFormatter
)Uma instância de optparse.HelpFormatter que será usada para exibir um texto de ajuda.
optparse
fornece duas classes concretas para essa finalidade: IndentedHelpFormatter e TitledHelpFormatter.add_help_option
(padrão:True
)Se verdadeiro,
optparse
adicionará uma opção de ajuda (com strings de opção-h
e--help
) ao analisador sintático.prog
A string a ser usada ao expandir
%prog
emusage
eversion
em vez deos.path.basename(sys.argv[0])
.epilog
(padrão:None
)Um parágrafo de texto de ajuda para exibir após a ajuda da opção.
Preenchendo o analisador sintático¶
Há várias maneiras de preencher o analisador sintático com opções. A maneira preferida é usando OptionParser.add_option()
, como mostrado na seção Tutorial. add_option()
pode ser chamado de uma das duas maneiras:
passar uma instância de Option (conforme retornado por
make_option()
)passar qualquer combinação de argumentos nomeados e posicionais que sejam aceitáveis para
make_option()
(ou seja, para o construtor de Option), e ela criará a instância de Option para você
A outra alternativa é passar uma lista de instâncias de Option pré-construídas para o construtor de OptionParser, como em:
option_list = [
make_option("-f", "--filename",
action="store", type="string", dest="filename"),
make_option("-q", "--quiet",
action="store_false", dest="verbose"),
]
parser = OptionParser(option_list=option_list)
(make_option()
é uma função de fábrica para criar instâncias de Option; atualmente é um apelido para o construtor de Option. Uma versão futura de optparse
pode dividir Option em várias classes, e make_option()
escolherá a classe certa para instanciar. Não instancie Option diretamente.)
Definindo as opções¶
Cada instância de Option representa um conjunto de strings de opções de linha de comando sinônimas, por exemplo, -f
e --file
. Você pode especificar qualquer número de strings de opções curtas ou longas, mas deve especificar pelo menos uma string de opção geral.
A maneira canônica de criar uma instância de Option
é com o método add_option()
de OptionParser
.
- OptionParser.add_option(option)¶
- OptionParser.add_option(*opt_str, attr=value, ...)
Para definir uma opção com apenas uma sequência de opções curta:
parser.add_option("-f", attr=value, ...)
E para definir uma opção com apenas uma longa sequência de opções:
parser.add_option("--foo", attr=value, ...)
Os argumentos nomeados definem atributos do novo objeto Option. O atributo option mais importante é
action
, e ele determina amplamente quais outros atributos são relevantes ou obrigatórios. Se você passar atributos option irrelevantes, ou deixar de passar os obrigatórios,optparse
levanta uma exceçãoOptionError
explicando seu erro.A action de uma opção determina o que
optparse
faz quando encontra essa opção na linha de comando. As ações de opção padrão codificadas nooptparse
são:"store"
armazena o argumento desta opção (padrão)
"store_const"
armazena um valor constante, predefinido via
Option.const
"store_true"
armazena
True
"store_false"
armazena
False
"append"
anexa o argumento desta opção a uma lista
"append_const"
anexar um valor constante a uma lista, predefinido via
Option.const
"count"
incrementa um contador em um
"callback"
chama uma função especificada
"help"
exibe uma mensagem de uso incluindo todas as opções e a documentação para elas
(Se você não fornecer uma ação, o padrão é
"store"
. Para esta ação, você também pode fornecer os atributos de opçãotype
edest
; consulte Ações de opção padrão.)
Como você pode ver, a maioria das ações envolve armazenar ou atualizar um valor em algum lugar. optparse
sempre cria um objeto especial para isso, convencionalmente chamado de options
, que é uma instância de optparse.Values
.
- class optparse.Values¶
Um objeto que contém nomes e valores de argumentos analisados como atributos. Normalmente criado chamando ao chamar
OptionParser.parse_args()
, e pode ser substituído por uma subclasse personalizada passada para o argumento values deOptionParser.parse_args()
(conforme descrito em Análise de argumentos).
Argumentos de opção (e vários outros valores) são armazenados como atributos deste objeto, de acordo com o atributo de opção dest
(destino).
Por exemplo, quando você chama
parser.parse_args()
uma das primeiras coisas que optparse
faz é criar o objeto options
:
options = Values()
Se uma das opções neste analisador sintático for definida com
parser.add_option("-f", "--file", action="store", type="string", dest="filename")
e a linha de comando que está sendo analisada inclui qualquer um dos seguintes:
-ffoo
-f foo
--file=foo
--file foo
então optparse
, ao ver esta opção, fará o equivalente a
options.filename = "foo"
Os atributos de opção type
e dest
são quase tão importantes quanto action
, mas action
é o único que faz sentido para todas as opções.
Atributos da classe Option¶
- class optparse.Option¶
Um único argumento de linha de comando, com vários atributos passados como nomeados para o construtor. Normalmente criado com
OptionParser.add_option()
em vez de diretamente, e pode ser substituído por uma classe personalizada por meio do argumento option_class paraOptionParser
.
Os seguintes atributos de opção podem ser passados como argumentos nomeados para OptionParser.add_option()
. Se você passar um atributo de opção que não seja relevante para uma opção específica, ou deixar de passar um atributo de opção obrigatório, optparse
levanta OptionError
.
- Option.action¶
(padrão:
"store"
)Determina o comportamento de
optparse
quando esta opção é vista na linha de comando; as opções disponíveis estão documentadas aqui.
- Option.type¶
(padrão:
"string"
)O tipo de argumento esperado por esta opção (por exemplo,
"string"
ou"int"
); os tipos de opções disponíveis estão documentados aqui.
- Option.dest¶
(padrão: derivado de strings de opção)
Se a ação da opção implicar escrever ou modificar um valor em algum lugar, isso informa ao
optparse
onde escrevê-lo:dest
nomeia um atributo do objetooptions
que ooptparse
constrói ao analisar a linha de comando.
- Option.default¶
O valor para usar para o destino desta opção se a opção não for vista na linha de comando. Veja também
OptionParser.set_defaults()
.
- Option.nargs¶
(padrão: 1)
Quantos argumentos do tipo
type
devem ser consumidos quando esta opção for vista. Se > 1,optparse
armazenará uma tupla de valores emdest
.
- Option.const¶
Para ações que armazenam um valor constante, o valor constante a ser armazenado.
- Option.choices¶
Para opções do tipo
"choice"
, a lista de strings que o usuário pode escolher.
- Option.callback¶
Para opções com ação
"callback"
, o chamável para chamar quando esta opção for vista. Veja a seção Funções de retorno de opção para detalhes sobre os argumentos passados para o chamável.
- Option.callback_args¶
- Option.callback_kwargs¶
Argumentos nomeados e posicionais adicionais para passar para
callback
após os quatro argumentos de retorno de chamada padrão.
Ações de opção padrão¶
As várias ações de opção têm requisitos e efeitos ligeiramente diferentes. A maioria das ações tem vários atributos de opção relevantes que você pode especificar para guiar o comportamento de optparse
; algumas têm atributos obrigatórios, que você deve especificar para qualquer opção que use essa ação.
"store"
[relevante:type
,dest
,nargs
,choices
]A opção deve ser seguida por um argumento, que é convertido em um valor de acordo com
type
e armazenado emdest
. Senargs
> 1, vários argumentos serão consumidos da linha de comando; todos serão convertidos de acordo comtype
e armazenados emdest
como uma tupla. Veja a seção Tipos de opção padrão.Se
choices
for fornecido (uma lista ou tupla de strings), o tipo padrão será"choice"
.Se
type
não for fornecido, o padrão será"string"
.Se
dest
não for fornecido,optparse
deriva um destino da primeira string de opção longa (por exemplo,--foo-bar
implicafoo_bar
). Se não houver strings de opção longas,optparse
deriva um destino da primeira string de opção curta (por exemplo,-f
implicaf
).Exemplo:
parser.add_option("-f") parser.add_option("-p", type="float", nargs=3, dest="point")
Como ele analisa a linha de comando
-f foo.txt -p 1 -3.5 4 -fbar.txt
optparse
vai definiroptions.f = "foo.txt" options.point = (1.0, -3.5, 4.0) options.f = "bar.txt"
"store_const"
[obrigatório:const
; relevante:dest
]O valor de
const
é armazenado emdest
.Exemplo:
parser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbose") parser.add_option("-v", "--verbose", action="store_const", const=1, dest="verbose") parser.add_option("--noisy", action="store_const", const=2, dest="verbose")
Se
--noisy
é encontrado,optparse
vai definiroptions.verbose = 2
"store_true"
[relevante:dest
]Um caso especial de
"store_const"
que armazenaTrue
emdest
."store_false"
[relevante:dest
]Como
"store_true"
, mas armazenadFalse
.Exemplo:
parser.add_option("--clobber", action="store_true", dest="clobber") parser.add_option("--no-clobber", action="store_false", dest="clobber")
"append"
[relevante:type
,dest
,nargs
,choices
]A opção deve ser seguida por um argumento, que é anexado à lista em
dest
. Se nenhum valor padrão paradest
for fornecido, uma lista vazia será criada automaticamente quandooptparse
encontrar esta opção pela primeira vez na linha de comando. Senargs
> 1, vários argumentos serão consumidos e uma tupla de comprimentonargs
será anexada adest
.Os padrões para
type
edest
são os mesmos da ação"store"
.Exemplo:
parser.add_option("-t", "--tracks", action="append", type="int")
Se
-t3
for encontrado na linha de comando,optparse
faz o equivalente a:options.tracks = [] options.tracks.append(int("3"))
Se, um pouco mais tarde,
--tracks=4
for encontrado, ele faz:options.tracks.append(int("4"))
A ação
append
chama o métodoappend
no valor atual da opção. Isso significa que qualquer valor padrão especificado deve ter um métodoappend
. Isso também significa que se o valor padrão não for vazio, os elementos padrão estarão presentes no valor analisado para a opção, com quaisquer valores da linha de comando anexados após esses valores padrão:>>> parser.add_option("--files", action="append", default=['~/.mypkg/defaults']) >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg']) >>> opts.files ['~/.mypkg/defaults', 'overrides.mypkg']
"append_const"
[obrigatório:const
; relevante:dest
]Como
"store_const"
, mas o valor deconst
é anexado adest
; assim como em"append"
,dest
assume como padrãoNone
, e uma lista vazia é criada automaticamente na primeira vez que a opção é encontrada."count"
[relevante:dest
]Incrementa o inteiro armazenado em
dest
. Se nenhum valor padrão for fornecido,dest
é definido como zero antes de ser incrementado pela primeira vez.Exemplo:
parser.add_option("-v", action="count", dest="verbosity")
A primeira vez que
-v
é encontrado na linha de comando,optparse
faz o equivalente a:options.verbosity = 0 options.verbosity += 1
Cada ocorrência subsequente de
-v
resulta emoptions.verbosity += 1
"callback"
[obrigatório:callback
; relevante:type
,nargs
,callback_args
,callback_kwargs
]Chama a função especificada por
callback
, que é chamada comofunc(option, opt_str, value, parser, *args, **kwargs)
Veja a seção Funções de retorno de opção para mais detalhes.
"help"
Exibe uma mensagem de ajuda completa para todas as opções no analisador sintático de opções atual. A mensagem de ajuda é construída a partir da string
usage
passada para o construtor do OptionParser e da stringhelp
passada para cada opção.Se nenhuma string de
help
for fornecida para uma opção, ela ainda será listada na mensagem de ajuda. Para omitir uma opção completamente, use o valor especialoptparse.SUPPRESS_HELP
.optparse
adiciona automaticamente uma opçãohelp
a todos as instâncias de OptionParsers, então normalmente você não precisa criar uma.Exemplo:
from optparse import OptionParser, SUPPRESS_HELP # geralmente, uma opção de ajuda é adicionada # automaticamente, mas que podem ser suprimida # usando o argumento add_help_option parser = OptionParser(add_help_option=False) parser.add_option("-h", "--help", action="help") parser.add_option("-v", action="store_true", dest="verbose", help="Be moderately verbose") parser.add_option("--file", dest="filename", help="Input file to read data from") parser.add_option("--secret", help=SUPPRESS_HELP)
Se
optparse
encontrar-h
ou--help
na linha de comando, ele vai exibir algo como a seguinte mensagem de ajuda no stdout (presumindo quesys.argv[0]
é"foo.py"
):Usage: foo.py [options] Options: -h, --help Show this help message and exit -v Be moderately verbose --file=FILENAME Input file to read data from
Após exibir a mensagem de ajuda,
optparse
encerra seu processo comsys.exit(0)
."version"
Exibe o número da versão fornecido à instância de OptionParser para stdout e sai. O número da versão é realmente formatado e exibido pelo método
print_version()
do OptionParser. Geralmente, é relevante somente se o argumentoversion
for fornecido ao construtor de OptionParser. Assim como com as opções dehelp
, você raramente criará opçõesversion
, já queoptparse
as adiciona automaticamente quando necessário.
Tipos de opção padrão¶
optparse
tem cinco tipos de opções embutidos: "string"
, "int"
, "choice"
, "float"
e "complex"
. Se você precisar adicionar novos tipos de opções, veja a seção Estendendo optparse.
Os argumentos para opções de string não são verificados ou convertidos de forma alguma: o texto na linha de comando é armazenado no destino (ou passado para a função de retorno) como está.
Argumentos inteiros (tipo "int"
) são analisados da seguinte forma:
se o número começar com
0x
, ele será analisado como um número hexadecimalse o número começar com
0
, ele será analisado como um número octalse o número começar com
0b
, ele será analisado como um número bináriocaso contrário, o número é analisado como um número decimal
A conversão é feita chamando int()
com a base apropriada (2, 8, 10 ou 16). Se isso falhar, optparse
também falhará, embora com uma mensagem de erro mais útil.
Os argumentos de opção "float"
e "complex"
são convertidos diretamente com float()
e complex()
, com tratamento de erros semelhante.
As opções "choice"
são um subtipo das opções "string"
. O atributo da opção choices
(uma sequência de strings) define o conjunto de argumentos de opção permitidos. optparse.check_choice()
compara os argumentos de opção fornecidos pelo usuário com esta lista mestre e levanta OptionValueError
se uma string inválida for fornecida.
Análise de argumentos¶
O objetivo de criar e preencher uma instância de OptionParser é chamar seu método parse_args()
.
- OptionParser.parse_args(args=None, values=None)¶
Analisa as opções de linha de comando encontradas em args.
Os parâmetros de entrada são
args
a lista de argumentos para processar (padrão:
sys.argv[1:]
)values
um objeto
Values
para armazenar argumentos de opção (padrão: uma nova instância deValues
) – se você fornecer um objeto existente, os padrões de opção não serão inicializados nele
e o valor de retorno é um par
(options, args)
sendooptions
o mesmo objeto que foi passado como values, ou a instância
optparse.Values
criada poroptparse
args
os argumentos posicionais restantes depois que todas as opções foram processadas
O uso mais comum é não fornecer nenhum argumento nomeado. Se você fornecer values
, ele será modificado com chamadas repetidas de setattr()
(aproximadamente uma para cada argumento de opção armazenado em um destino de opção) e retornado por parse_args()
.
Se parse_args()
encontrar algum erro na lista de argumentos, ele chama o método error()
da instância de OptionParser com uma mensagem de erro apropriada para o usuário final. Isso, em última análise, encerra seu processo com um status de saída 2 (o status de saída tradicional do Unix para erros de linha de comando).
Consultando e manipulando seu analisador sintático de opções¶
O comportamento padrão do analisador sintático de opções pode ser ligeiramente personalizado, e você também pode dar uma olhada no seu analisador de opções e ver o que há lá. A classe OptionParser fornece vários métodos para ajudar você:
- OptionParser.disable_interspersed_args()¶
Define a análise para parar na primeira não opção. Por exemplo, se
-a
e-b
forem ambas opções simples que não aceitam argumentos,optparse
normalmente aceita esta sintaxe:prog -a arg1 -b arg2
e trata-a como equivalente a
prog -a -b arg1 arg2
Para desabilitar esse recurso, chame
disable_interspersed_args()
. Isso restaura a sintaxe Unix tradicional, onde a análise de opções para com o primeiro argumento não-opcional.Use isto se você tiver um processador de comando que executa outro comando que tem opções próprias e você quer ter certeza de que essas opções não fiquem confusas. Por exemplo, cada comando pode ter um conjunto diferente de opções.
- OptionParser.enable_interspersed_args()¶
Define a análise para não parar na primeira não opção, permitindo intercalar alternadores com argumentos de comando. Esse é o comportamento padrão.
- OptionParser.get_option(opt_str)¶
Retorna a instância de Option com a string de opção opt_str, ou
None
se nenhuma opção tiver essa string de opção.
- OptionParser.has_option(opt_str)¶
Retorna
True
se o objeto OptionParser tiver uma opção com string de opção opt_str (por exemplo,-q
ou--verbose
).
- OptionParser.remove_option(opt_str)¶
Se o
OptionParser
tiver uma opção correspondente a opt_str, essa opção será removida. Se essa opção fornecer quaisquer outras strings de opção, todas essas strings de opção se tornarão inválidas. Se opt_str não ocorrer em nenhuma opção pertencente a esteOptionParser
, levantaValueError
.
Conflitos entre opções¶
Se você não tomar cuidado, é fácil definir opções com strings de opções conflitantes:
parser.add_option("-n", "--dry-run", ...)
...
parser.add_option("-n", "--noisy", ...)
(Isto é particularmente verdadeiro se você definiu sua própria subclasse de OptionParser com algumas opções padrão.)
Toda vez que você adiciona uma opção, optparse
verifica se há conflitos com opções existentes. Se encontrar algum, ele invoca o mecanismo de tratamento de conflitos atual. Você pode definir o mecanismo de tratamento de conflitos no construtor:
parser = OptionParser(..., conflict_handler=handler)
ou com uma chamada separada:
parser.set_conflict_handler(handler)
Os manipuladores de conflitos disponíveis são:
"error"
(padrão)presume que os conflitos de opções são um erro de programação e levanta
OptionConflictError
"resolve"
resolve conflitos de opções de forma inteligente (veja abaixo)
Como exemplo, vamos definir um OptionParser
que resolve conflitos de forma inteligente e adiciona opções conflitantes a ele:
parser = OptionParser(conflict_handler="resolve")
parser.add_option("-n", "--dry-run", ..., help="do no harm")
parser.add_option("-n", "--noisy", ..., help="be noisy")
Neste ponto, optparse
detecta que uma opção adicionada anteriormente já está usando a string de opção -n
. Como conflict_handler
é "resolve"
, ele resolve a situação removendo -n
da lista de strings de opção da opção anterior. Agora --dry-run
é a única maneira do usuário ativar essa opção. Se o usuário pedir ajuda, a mensagem de ajuda refletirá isso:
Options:
--dry-run do no harm
...
-n, --noisy be noisy
É possível reduzir as strings de opção para uma opção adicionada anteriormente até que não haja mais nenhuma, e o usuário não tenha como invocar essa opção da linha de comando. Nesse caso, optparse
remove essa opção completamente, então ela não aparece no texto de ajuda ou em nenhum outro lugar. Continuando com nosso objeto OptionParser existente:
parser.add_option("--dry-run", ..., help="new dry-run option")
Neste ponto, a opção original -n
/--dry-run
não está mais acessível, então optparse
a remove, deixando este texto de ajuda:
Options:
...
-n, --noisy be noisy
--dry-run new dry-run option
Limpeza¶
As instâncias de OptionParser têm várias referências cíclicas. Isso não deve ser um problema para o coletor de lixo do Python, mas você pode desejar quebrar as referências cíclicas explicitamente chamando destroy()
no seu OptionParser quando terminar de usá-lo. Isso é particularmente útil em aplicações de longa execução, onde gráficos de objetos grandes podem ser acessados do seu OptionParser.
Outros métodos¶
OptionParser provê vários outros métodos públicos:
- OptionParser.set_usage(usage)¶
Defina a string de uso de acordo com as regras descritas acima para o argumento nomeado do construtor
usage
. PassarNone
define a string de uso padrão; useoptparse.SUPPRESS_USAGE
para suprimir uma mensagem de uso.
- OptionParser.print_usage(file=None)¶
Exibe a mensagem de uso para o programa atual (
self.usage
) em file (stdout padrão). Qualquer ocorrência da string%prog
emself.usage
é substituída pelo nome do programa atual. Não faz nada seself.usage
estiver vazio ou não definido.
- OptionParser.get_usage()¶
O mesmo que
print_usage()
, mas retorna a string de uso em vez de exibi-la.
- OptionParser.set_defaults(dest=value, ...)¶
Define valores padrão para vários destinos de opção de uma vez. Usar
set_defaults()
é a maneira preferida de definir valores padrão para opções, já que várias opções podem compartilhar o mesmo destino. Por exemplo, se várias opções de “modo” definirem o mesmo destino, qualquer uma delas pode definir o padrão, e a última vence:parser.add_option("--advanced", action="store_const", dest="mode", const="advanced", default="novice") # substituída abaixo parser.add_option("--novice", action="store_const", dest="mode", const="novice", default="advanced") # substitui a configuração acima
Para evitar essa confusão, use
set_defaults()
:parser.set_defaults(mode="advanced") parser.add_option("--advanced", action="store_const", dest="mode", const="advanced") parser.add_option("--novice", action="store_const", dest="mode", const="novice")
Funções de retorno de opção¶
Quando as ações e tipos embutidos de optparse
não são o bastante para suas necessidades, você tem duas escolhas: estender optparse
ou definir uma opção de retorno de chamada. Estender optparse
é mais geral, mas exagero para muitos casos simples. Muitas vezes, um retorno de chamada simples é tudo o que você precisa.
Há duas etapas para definir uma opção de retorno de chamada:
definir a opção em si usando a ação
"callback"
escrever o função de retorno; esta é uma função (ou método) que recebe pelo menos quatro argumentos, conforme descrito abaixo
Definindo uma opção de retorno de chamada¶
Como sempre, a maneira mais fácil de definir uma opção de retorno de chamada é usando o método OptionParser.add_option()
. Além de action
, o único atributo de opção que você deve especificar é callback
, a função a ser chamada:
parser.add_option("-c", action="callback", callback=my_callback)
callback
é uma função (ou outro objeto chamável), então você já deve ter definido my_callback()
quando criar esta opção de retorno de chamada. Neste caso simples, optparse
nem sabe se -c
aceita argumentos, o que geralmente significa que a opção não aceita argumentos — a mera presença de -c
na linha de comando é tudo o que ela precisa saber. Em algumas circunstâncias, no entanto, você pode querer que seu retorno de chamada consuma um número arbitrário de argumentos de linha de comando. É aqui que escrever retornos de chamada fica complicado; isso é abordado mais adiante nesta seção.
optparse
sempre passa quatro argumentos particulares para seu retorno de chamada, e ele só passará argumentos adicionais se você especificá-los via callback_args
e callback_kwargs
. Assim, a assinatura mínima da função de retorno de chamada é:
def my_callback(option, opt, value, parser):
Os quatro argumentos para um retorno de chamada são descritos abaixo.
Há vários outros atributos de opção que você pode fornecer ao definir uma opção de retorno de chamada:
type
tem seu significado usual: como com as ações
"store"
ou"append"
, ele instruioptparse
a consumir um argumento e convertê-lo paratype
. Em vez de armazenar o(s) valor(es) convertido(s) em qualquer lugar, no entanto,optparse
os passa para sua função de retorno de chamada.nargs
também tem seu significado usual: se for fornecido e > 1,
optparse
consumirá argumentosnargs
, cada um dos quais deve ser conversível paratype
. Em seguida, ele passa uma tupla de valores convertidos para seu retorno de chamada.callback_args
uma tupla de argumentos posicionais extras para passar para a função de retorno
callback_kwargs
um dicionário de argumentos nomeados extras para passar para a função de retorno
Como os retornos de chamada são chamados¶
Todos os retornos de chamada são chamados da seguinte forma:
func(option, opt_str, value, parser, *args, **kwargs)
onde
option
é a instância de Option que está chamando o retorno de chamada
opt_str
é a string de opção vista na linha de comando que está acionando o retorno de chamada. (Se uma opção longa abreviada foi usada,
opt_str
será a string de opção canônica completa — por exemplo, se o usuário colocar--foo
na linha de comando como uma abreviação para--foobar
, entãoopt_str
será"--foobar"
.)value
é o argumento para esta opção visto na linha de comando.
optparse
só esperará um argumento setype
estiver definido; o tipo devalue
será o tipo implícito pelo tipo da opção. Setype
para esta opção forNone
(nenhum argumento esperado), entãovalue
seráNone
. Senargs
> 1,value
será uma tupla de valores do tipo apropriado.parser
é a instância OptionParser que controla tudo, útil principalmente porque você pode acessar alguns outros dados interessantes por meio de seus atributos de instância:
parser.largs
a lista atual de argumentos restantes, ou seja, argumentos que foram consumidos, mas não são opções nem argumentos de opção. Sinta-se à vontade para modificar
parser.largs
, por exemplo, adicionando mais argumentos a ele. (Esta lista se tornaráargs
, o segundo valor de retorno deparse_args()
.)parser.rargs
a lista atual de argumentos restantes, ou seja, com
opt_str
evalue
(se aplicável) removidos, e apenas os argumentos que os seguem ainda lá. Sinta-se à vontade para modificarparser.rargs
, por exemplo, consumindo mais argumentos.parser.values
o objeto onde os valores de opção são armazenados por padrão (uma instância de optparse.OptionValues). Isso permite que as função de retorno usem o mesmo mecanismo que o resto de
optparse
para armazenar valores de opção; você não precisa mexer com globais ou closures. Você também pode acessar ou modificar o(s) valor(es) de quaisquer opções já encontradas na linha de comando.
args
é uma tupla de argumentos posicionais arbitrários fornecidos por meio do atributo de opção
callback_args
.kwargs
é um dicionário de argumentos nomeados arbitrários fornecidos via
callback_kwargs
.
Levantando erros em uma função de retorno¶
A função de retorno de chamada deve levantar OptionValueError
se houver algum problema com a opção ou seu(s) argumento(s). optparse
captura isso e encerra o programa, exibindo a mensagem de erro que você fornece para stderr. Sua mensagem deve ser clara, concisa, precisa e mencionar a opção com defeito. Caso contrário, o usuário terá dificuldade em descobrir o que fez de errado.
Exemplo de função de retorno 1: retorno de chamada trivial¶
Aqui está um exemplo de uma opção de retorno de chamada que não aceita argumentos e simplesmente registra que a opção foi vista:
def record_foo_seen(option, opt_str, value, parser):
parser.values.saw_foo = True
parser.add_option("--foo", action="callback", callback=record_foo_seen)
Claro, você pode fazer isso com a ação "store_true"
.
Exemplo de função de retorno 2: verificar a ordem das opções¶
Aqui está um exemplo um pouco mais interessante: registra o fato de que -a
é visto, mas explode se ele vier depois de -b
na linha de comando.
def check_order(option, opt_str, value, parser):
if parser.values.b:
raise OptionValueError("can't use -a after -b")
parser.values.a = 1
...
parser.add_option("-a", action="callback", callback=check_order)
parser.add_option("-b", action="store_true", dest="b")
Exemplo 3 de função de retorno: verificar a ordem das opções (generalizada)¶
Se você quiser reutilizar essa função de retorno para várias opções semelhantes (definir um sinalizador, mas explodir se -b
já tiver sido visto), será preciso um pouco de trabalho: a mensagem de erro e o sinalizador que ele define devem ser generalizados.
def check_order(option, opt_str, value, parser):
if parser.values.b:
raise OptionValueError("can't use %s after -b" % opt_str)
setattr(parser.values, option.dest, 1)
...
parser.add_option("-a", action="callback", callback=check_order, dest='a')
parser.add_option("-b", action="store_true", dest="b")
parser.add_option("-c", action="callback", callback=check_order, dest='c')
Exemplo de função de retorno 4: verificar uma condição arbitrária¶
Claro, você pode colocar qualquer condição ali—você não está limitado a verificar os valores de opções já definidas. Por exemplo, se você tem opções que não devem ser chamadas quando a lua está cheia, tudo o que você tem a fazer é isto:
def check_moon(option, opt_str, value, parser):
if is_moon_full():
raise OptionValueError("%s option invalid when moon is full"
% opt_str)
setattr(parser.values, option.dest, 1)
...
parser.add_option("--foo",
action="callback", callback=check_moon, dest="foo")
(A definição de is_moon_full()
é deixada como um exercício para o leitor.)
Exemplo de função de retorno 5: argumentos fixos¶
As coisas ficam um pouco mais interessantes quando você define opções de retorno de chamada que aceitam um número fixo de argumentos. Especificar que uma opção de retorno de chamada aceita argumentos é semelhante a definir uma opção "store"
ou "append"
: se você definir type
, então a opção aceita um argumento que deve ser conversível para esse tipo; se você definir ainda nargs
, então a opção aceita argumentos nargs
.
Aqui está um exemplo que apenas emula a ação padrão "store"
:
def store_value(option, opt_str, value, parser):
setattr(parser.values, option.dest, value)
...
parser.add_option("--foo",
action="callback", callback=store_value,
type="int", nargs=3, dest="foo")
Note que optparse
cuida de consumir 3 argumentos e convertê-los em números inteiros para você; tudo o que você precisa fazer é armazená-los. (Ou o que for; obviamente você não precisa de uma função de retorno de chamada para este exemplo.)
Exemplo de função de retorno 6: argumentos variáveis¶
As coisas ficam complicadas quando você quer que uma opção receba um número variável de argumentos. Para esse caso, você deve escrever uma função de retorno, pois optparse
não fornece nenhuma capacidade embutida para ele. E você tem que lidar com certas complexidades da análise sintática de linha de comando Unix convencional que optparse
normalmente lida para você. Em particular, as funções de retorno devem implementar as regras convencionais para argumentos --
e -
simples:
--
ou-
podem ser argumentos de opção--
apenas (se não for o argumento para alguma opção): interrompe o processamento da linha de comando e descarta o--
-
apenas (se não for o argumento para alguma opção): interrompe o processamento da linha de comando, mas mantém o-
(anexa-o aparser.largs
)
Se você quiser uma opção que aceite um número variável de argumentos, há várias questões sutis e complicadas com as quais se preocupar. A implementação exata que você escolher será baseada em quais compensações você está disposto a fazer para sua aplicação (é por isso que optparse
não oferece suporte a esse tipo de coisa diretamente).
No entanto, aqui vai uma tentativa de função de retorno para uma opção com argumentos variáveis:
def vararg_callback(option, opt_str, value, parser):
assert value is None
value = []
def floatable(str):
try:
float(str)
return True
except ValueError:
return False
for arg in parser.rargs:
# para em --foo como opções
if arg[:2] == "--" and len(arg) > 2:
break
# para em -a, mas não em -3 ou -3.0
if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
break
value.append(arg)
del parser.rargs[:len(value)]
setattr(parser.values, option.dest, value)
...
parser.add_option("-c", "--callback", dest="vararg_attr",
action="callback", callback=vararg_callback)
Estendendo optparse
¶
Como os dois principais fatores de controle sobre como optparse
interpreta as opções de linha de comando são a ação e o tipo de cada opção, a direção mais provável de extensão é adicionar novas ações e novos tipos.
Adicionando novos tipos¶
Para adicionar novos tipos, você precisa definir sua própria subclasse da classe Option
de optparse
. Esta classe tem alguns atributos que definem os tipos de optparse
: TYPES
e TYPE_CHECKER
.
- Option.TYPES¶
Uma tupla de nomes de tipos; na sua subclasse, basta definir uma nova tupla
TYPES
que se baseia na tupla padrão.
- Option.TYPE_CHECKER¶
Um dicionário que mapeia nomes de tipos para funções de verificação de tipos. Uma função de verificação de tipos tem a seguinte assinatura:
def check_mytype(option, opt, value)
sendo
option
uma instânciaOption
,opt
é uma string de opção (por exemplo,-f
), evalue
é a string da linha de comando que deve ser verificada e convertida para o tipo desejado.check_mytype()
deve retornar um objeto do tipo hipotéticomytype
. O valor retornado por uma função de verificação de tipo acabará na instância OptionValues retornada porOptionParser.parse_args()
, ou será passado para uma função de retorno como o parâmetrovalue
.Sua função de verificação de tipo deve levantar
OptionValueError
se encontrar algum problema.OptionValueError
recebe um único argumento de string, que é passado como está para o métodoerror()
doOptionParser
, que por sua vez adiciona o nome do programa e a string"error:"
e exibe tudo no stderr antes de encerrar o processo.
Aqui está um exemplo bobo que demonstra a adição de um tipo de opção "complex"
para analisar números complexos no estilo Python na linha de comando. (Isso é ainda mais bobo do que costumava ser, porque optparse
1.3 adicionou suporte embutido para números complexos, mas não importa.)
Primeiro, as importações necessárias:
from copy import copy
from optparse import Option, OptionValueError
Você precisa definir seu verificador de tipo primeiro, pois ele será referenciado mais tarde (no atributo de classe TYPE_CHECKER
da sua subclasse de Option):
def check_complex(option, opt, value):
try:
return complex(value)
except ValueError:
raise OptionValueError(
"option %s: invalid complex value: %r" % (opt, value))
Finalmente, a subclasse de Option:
class MyOption (Option):
TYPES = Option.TYPES + ("complex",)
TYPE_CHECKER = copy(Option.TYPE_CHECKER)
TYPE_CHECKER["complex"] = check_complex
(Se não fizéssemos uma copy()
de Option.TYPE_CHECKER
, acabaríamos modificando o atributo TYPE_CHECKER
da classe Option de optparse
. Sendo Python, nada impede você de fazer isso, exceto boas maneiras e bom senso.)
Pronto! Agora você pode escrever um script que usa o novo tipo de opção como qualquer outro script baseado em optparse
, exceto que você tem que instruir seu OptionParser a usar MyOption em vez de Option:
parser = OptionParser(option_class=MyOption)
parser.add_option("-c", type="complex")
Como alternativa, você pode criar sua própria lista de opções e passá-la para o OptionParser; se você não usar add_option()
da maneira acima, não precisa informar ao OptionParser qual classe de opção usar:
option_list = [MyOption("-c", action="store", type="complex", dest="c")]
parser = OptionParser(option_list=option_list)
Adicionando novas ações¶
A adição de novas ações é um pouco mais complicado, porque você precisa entender que optparse
tem algumas classificações para ações:
- Ações “store”
ações que resultam em
optparse
armazenando um valor em um atributo da instância OptionValues atual; essas opções exigem que um atributodest
seja fornecido ao construtor Option.- Ações “typed”
Ações que pegam um valor da linha de comando e esperam que ele seja de um certo tipo; ou melhor, uma string que pode ser convertida para um certo tipo. Essas opções requerem um atributo
type
para o construtor Option.
Esses são conjuntos sobrepostos: algumas ações “store” padrão são "store"
, "store_const"
, "append"
e "count"
, enquanto as ações “typed” padrão são "store"
, "append"
e "callback"
.
Ao adicionar uma ação, você precisa categorizá-la listando-a em pelo menos um dos seguintes atributos de classe de Option (todos são listas de strings):
- Option.ACTIONS¶
Todas as ações devem ser listadas em ACTIONS.
- Option.STORE_ACTIONS¶
As ações “store” também são listadas aqui.
- Option.TYPED_ACTIONS¶
As ações “typed” também são listadas aqui.
- Option.ALWAYS_TYPED_ACTIONS¶
Ações que sempre assumem um tipo (ou seja, cujas opções sempre assumem um valor) são listadas aqui adicionalmente. O único efeito disso é que
optparse
atribui o tipo padrão,"string"
, a opções sem tipo explícito cuja ação é listada emALWAYS_TYPED_ACTIONS
.
Para realmente implementar sua nova ação, você deve substituir o método take_action()
de Option e adicionar um caso que reconheça sua ação.
Por exemplo, vamos adicionar uma ação "extend"
. Isso é semelhante à ação padrão "append"
, mas em vez de pegar um único valor da linha de comando e anexá-lo a uma lista existente, "extend"
pegará vários valores em uma única string delimitada por vírgulas e estenderá uma lista existente com eles. Ou seja, se --names
for uma opção "extend"
do tipo "string"
, a linha de comando
--names=foo,bar --names blah --names ding,dong
resultaria em uma lista
["foo", "bar", "blah", "ding", "dong"]
Novamente, nós definimos uma subclasse de Option:
class MyOption(Option):
ACTIONS = Option.ACTIONS + ("extend",)
STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
def take_action(self, action, dest, opt, value, values, parser):
if action == "extend":
lvalue = value.split(",")
values.ensure_value(dest, []).extend(lvalue)
else:
Option.take_action(
self, action, dest, opt, value, values, parser)
Características de nota:
"extend"
espera um valor na linha de comando e armazena esse valor em algum lugar, então ele vai emSTORE_ACTIONS
eTYPED_ACTIONS
.para garantir que
optparse
atribua o tipo padrão de"string"
às ações"extend"
, colocamos a ação"extend"
emALWAYS_TYPED_ACTIONS
também.MyOption.take_action()
implementa apenas esta nova ação e passa o controle de volta paraOption.take_action()
para as ações padrãooptparse
.values
é uma instância da classe optparse_parser.Values, que fornece o método muito útilensure_value()
.ensure_value()
é essencialmentegetattr()
com uma válvula de segurança; é chamado comovalues.ensure_value(attr, value)
Se o atributo
attr
devalues
não existir ou forNone
, então ensure_value() primeiro o define comovalue
e então retornavalue
. Isso é muito útil para ações como"extend"
,"append"
e"count"
, todas as quais acumulam dados em uma variável e esperam que essa variável seja de um certo tipo (uma lista para as duas primeiras, um inteiro para a última). Usarensure_value()
significa que os scripts que usam sua ação não precisam se preocupar em definir um valor padrão para os destinos de opção em questão; eles podem simplesmente deixar o padrão comoNone
eensure_value()
cuidará de acertar quando for necessário.
Exceções¶
- exception optparse.OptionError¶
Levantada se uma instância de
Option
for criada com argumentos inválidos ou inconsistentes.
- exception optparse.OptionConflictError¶
Levantada se opções conflitantes forem adicionadas a um instância de
OptionParser
.
- exception optparse.OptionValueError¶
Levantada se um valor de opção inválido for encontrado na linha de comando.
- exception optparse.BadOptionError¶
Levantada se uma opção inválida for passada na linha de comando.
- exception optparse.AmbiguousOptionError¶
Levantada se uma opção ambígua for passada na linha de comando.