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.--en
Portanto, 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
y
yes
true
on
1
Os valores falsos são os seguintes.
n
no
f
false
off
0
Se 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'