Existe alguma maneira de convencer o Getopt do Python a lidar com parâmetros opcionais às opções?
-
20-09-2019 - |
Pergunta
De acordo com a documentação sobre o Python getopt
(Eu acho) os campos de opções devem se comportar como o getopt()
função. No entanto, não consigo permitir parâmetros opcionais ao meu código:
#!/usr/bin/python
import sys,getopt
if __name__ == "__main__":
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], "v::", ["verbose="])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
for o,a in opts:
if o in ("-v", "--verbose"):
if a:
verbose=int(a)
else:
verbose=1
print "verbosity is %d" % (verbose)
Resulta em:
$ ./testopt.py -v
option -v requires argument
$ ./testopt.py -v 1
verbosity is 1
Solução
getopt
Não suporta parâmetros opcionais. Em caso de longa opção, você pode fazer:
$ ./testopt.py --verbose=
o que resultará em valor de cordão vazio.
Você poderia encontrar argparse
módulo para ser mais flexível.
Outras dicas
Infelizmente, não há como. De Optparse Docs:
Normalmente, uma determinada opção leva um argumento ou não. Muitas pessoas querem um recurso "Argumentos de opções opcionais", o que significa que algumas opções assumirão um argumento se o virem, e não o fizerem. Isso é um tanto controverso, porque torna a análise ambígua: se "-a" aceita um argumento opcional e "-b" é outra opção completamente, como interpretamos "-Ab"? Devido a essa ambiguidade, o OptParse não suporta esse recurso.
EDITAR: Opa, isso é para o módulo optparse, não o módulo GOTOPT, mas o raciocínio por que nenhum dos módulos tem "argumentos opcionais de opções" é o mesmo para ambos.
Você pode fazer um parâmetro opcional com o GETOPT como este:
import getopt
import sys
longopts, shortopts = getopt.getopt(sys.argv[1:], shortopts='', longopts=['env='])
argDict = dict(longopts)
if argDict.has_key('--env') and argDict['--env'] == 'prod':
print "production"
else:
print "sandbox"
Uso:
$ python scratch.py --env=prod
production
$ python scratch.py --env=dev
sandbox
$ python scratch.py
sandbox
Se você estiver usando a versão 2.3 ou posterior, pode querer experimentar o optparse Em vez disso, o módulo, pois é "mais conveniente, flexível e poderoso ...", além de mais recente. Infelizmente, como Pynt respondeu, não parece possível obter exatamente o que você deseja.
O GETOpt do Python deve realmente suportar args opcionais, como o GNU getOpt, exigindo '=' 'para especificar um parâmetro. Agora você pode simulá -lo com bastante facilidade, com essa restrição mudando implicitamente -opção para --option =
Ou seja, você pode especificar que -opção requer um argumento e, em seguida, ajuste -opção para --ption = da seguinte forma:
for i, opt in enumerate(sys.argv):
if opt == '--option':
sys.argv[i] = '--option='
elif opt == '--':
break