Para lidar com argumentos de linha de comando em Python, usar os módulos argv ou argparse do módulo sys.
O módulo argparse permite um tratamento flexível dos argumentos da linha de comando, mas é preciso ter cuidado ao lidar com valores booleanos (verdadeiros, falsos).
A seguinte informação é fornecida aqui.
- argparse para uma fácil definição dos argumentos
- Especificar o tipo do argumento (tipo) com argparse
- Não especificar “bool” como tipo de argumento de add_argument()
- Julgamento por bool()
- Utilizar a acção de argumento em vez do tipo de argumento.
- Usando a função strtobool()
argparse para uma fácil definição dos argumentos
O módulo argparse facilita a definição de argumentos de linha de comando.
O módulo argparse torna fácil a criação de interfaces de linha de comando de fácil utilização. O utilizador define que argumentos o seu programa necessita, e argparse descobrirá como analisar essas opções a partir do módulo sys.argv. argparse gera automaticamente mensagens de ajuda e utilização, e levanta um erro se o utilizador especificar argumentos inválidos para o programa. erro quando o utilizador especifica argumentos inválidos para o programa.
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation
Especificar o tipo do argumento (tipo) com argparse
Uma característica útil da argparse é especificar o tipo (tipo).
Por exemplo, se especificar um tipo inteiro (int), converterá automaticamente o argumento em int e também levantará um erro para argumentos que não são int.
O tipo é especificado pelo tipo de argumento de add_argument().
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('arg_int', type=int)
args = parser.parse_args()
print(args.arg_int)
print(type(args.arg_int))
Execute este ficheiro a partir da linha de comando.
$ python argparse_type_int.py 100
100
<type 'int'>
Argumento 100 é lido como int.
Se um valor não-pintado for utilizado como argumento, ocorrerá um erro.
$ python argparse_type_int.py foo
usage: argparse_type_int.py [-h] arg_int
argparse_type_int.py: error: argument arg_int: invalid int value: 'foo'
$ python argparse_type_int.py 1.23
usage: argparse_type_int.py [-h] arg_int
argparse_type_int.py: error: argument arg_int: invalid int value: '1.23'
Muito útil para jogar argumentos inesperados.
Não especificar “bool” como tipo de argumento de add_argument()
É importante notar que bool, como int e float, não funcionará como esperado se especificar bool como o tipo de argumento de add_argument().
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('arg_bool', type=bool)
args = parser.parse_args()
print(args.arg_bool)
print(type(args.arg_bool))
Execute este ficheiro a partir da linha de comando.
$ python argparse_type_bool.py True
True
<type 'bool'>
Se for usado como argumento, será lido como um tipo de bool verdadeiro. Este é o comportamento esperado, mas o problema é o caso seguinte.
$ python argparse_type_bool.py False
True
<type 'bool'>
$ python argparse_type_bool.py bar
True
<type 'bool'>
Se usar falso ou qualquer outro fio como argumento, ele será lido como verdadeiro.
A razão porque isto acontece é que quando o tipo=xxx é especificado no add_argument(), o argumento é passado para xxx().
Por exemplo, se type=int, o argumento será passado para int(); se type=float, então float().
O mesmo é válido para type=bool, o que significa que o argumento será passado para bool().
Julgamento por bool()
Este bool() é complicado.
- bool() — Built-in Functions — Python 3.10.0 Documentation
- Truth Value Testing — Built-in Types — Python 3.10.0 Documentation
Os seguintes valores são considerados falsos:
- None
- false
- Zero em tipos numéricos. Por exemplo, os seguintes valores
- 0
- 0.0
- 0j
- Uma sequência vazia. Por exemplo
- ''
- ()
- []
- Cartografia vazia. Por exemplo
- {}
Todos os outros valores são assumidos como verdadeiros – assim, objectos de muitos tipos são sempre verdadeiros. Operações e funções incorporadas que retornam resultados booleanos retornam sempre 0 ou Falso como o falso valor e 1 ou Verdadeiro como o verdadeiro valor, a menos que se note o contrário.
Portanto, todas as cordas não vazias passadas a bool(), quer sejam “verdadeiras” ou “falsas”, voltarão a ser verdadeiras. Apenas as cordas vazias serão falsas.
print(bool('True'))
print(bool('False'))
print(bool('abc'))
# True
# True
# True
print(bool(''))
# False
Quando type=bool é definido em add_argument(), o argumento é passado para bool(). Portanto, como mostrado no exemplo acima, se falso for usado como argumento, será convertido por bool() como a string 'Falso' e lido como verdadeiro.
Utilizar a acção de argumento em vez do tipo de argumento.
Se quiser usar valores booleanos em argparse, especificar 'store_true' ou 'store_false' para a acção de argumento.
- 'store_true'
- 'store_false'
Estas serão versões especiais de 'store_const' que irão armazenar Verdadeiro e Falso, respectivamente. Além disso, definirão os valores por defeito para Falso e Verdadeiro respectivamente, por essa ordem.
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--en', action='store_true')
args = parser.parse_args()
print(args.en)
print(type(args.en))
Neste exemplo, são dadas as seguintes opções.--enPortanto, se o en não for definido como verdadeiro, será carregado como falso, que é o valor por defeito do en.
$ python argparse_option_bool.py --en
True
<type 'bool'>
$ python argparse_option_bool.py
False
<type 'bool'>
Se quiser definir o padrão como verdadeiro, e falso quando a opção é adicionada, basta fazer o seguinte.action='store_false'
Usando a função strtobool()
Se quiser usar argumentos posicionais em vez de opções, também pode usar a função strtobool().
strtobool() é uma função que converte uma corda em verdadeira (1) ou falsa (0).
Converte um fio booleano em verdadeiro (1) ou falso (0).
Os verdadeiros valores são os seguintes
yyestrueon1Os valores falsos são os seguintes.
nnoffalseoff0Se val não for nenhuma das anteriores, eleva o ValueError.
9. API Reference – strtobool() — Python 3.10.0 Documentation
Não é sensível a maiúsculas e minúsculas, por exemplo, pode usar o seguinte; qualquer outra cadeia resultará num erro.
'TRUE''True''YES'
from distutils.util import strtobool
print(strtobool('true'))
print(strtobool('True'))
print(strtobool('TRUE'))
# 1
# 1
# 1
print(strtobool('t'))
print(strtobool('yes'))
print(strtobool('y'))
print(strtobool('on'))
print(strtobool('1'))
# 1
# 1
# 1
# 1
# 1
print(strtobool('false'))
print(strtobool('False'))
print(strtobool('FALSE'))
# 0
# 0
# 0
print(strtobool('f'))
print(strtobool('no'))
print(strtobool('n'))
print(strtobool('off'))
print(strtobool('0'))
# 0
# 0
# 0
# 0
# 0
# print(strtobool('abc'))
# ValueError: invalid truth value 'abc'
O nome é strtobool(), mas o valor de retorno não é bool, mas int (1 ou 0).
print(type(strtobool('true')))
# <class 'int'>
Como escrito anteriormente, quando o tipo=xxx é especificado em add_argument() de argparse, o argumento será passado para xxx(). Por conseguinte, podemos fazer o seguinte.type=strtobool
import argparse
from distutils.util import strtobool
parser = argparse.ArgumentParser()
parser.add_argument('arg_bool', type=strtobool)
args = parser.parse_args()
print(args.arg_bool)
print(type(args.arg_bool))
O valor de retorno não é um tipo bool, mas um tipo int 1 ou 0, mas pode ler valores verdadeiros ou falsos com argumentos verdadeiros ou falsos.
$ python argparse_type_strtobool.py true
1
<type 'int'>
$ python argparse_type_strtobool.py false
0
<type 'int'>
Além disso, se o argumento não for esperado, será gerado um erro de forma adequada.
$ python argparse_type_strtobool.py bar
usage: argparse_type_strtobool.py [-h] arg_bool
argparse_type_strtobool.py: error: argument arg_bool: invalid strtobool value: 'bar'