Para xestionar argumentos da liña de comandos en Python, use os módulos argv ou argparse do módulo sys.
O módulo argparse permite un manexo flexible dos argumentos da liña de comandos, pero hai que ter coidado ao tratar con valores booleanos (true, false).
A seguinte información ofrécese aquí.
- argparse para facilitar a definición de argumentos
- Especifique o tipo de argumento (tipo) con argparse
- Non especifique “bool” como tipo de argumento de add_argument()
- Xuízo por bool()
- Use a acción de argumento en lugar do tipo de argumento.
- Usando a función strtobool().
argparse para facilitar a definición de argumentos
O módulo argparse facilita a definición de argumentos da liña de comandos.
O módulo argparse facilita a creación de interfaces de liña de comandos amigables. Vostede define que argumentos necesita o seu programa e argparse descubrirá como analizar esas opcións desde sys.argv. O módulo argparse xera automaticamente mensaxes de axuda e uso e xera un erro se o usuario especifica argumentos non válidos para o programa. erro cando o usuario especifica argumentos non válidos para o programa.
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation
Especifique o tipo de argumento (tipo) con argparse
Unha característica útil de argparse é especificar o tipo (tipo).
Por exemplo, se especifica un tipo enteiro (int), converterá automaticamente o argumento en int e tamén provocará un erro para os argumentos que non sexan int.
O tipo é especificado polo tipo de argumento 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))
Executar este ficheiro desde a liña de comandos.
$ python argparse_type_int.py 100
100
<type 'int'>
O argumento 100 lese como int.
Se se usa un valor non int como argumento, producirase un 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'
Moi útil para xogar argumentos inesperados.
Non especifique “bool” como tipo de argumento de add_argument()
É importante ter en conta que bool, como int e float, non funcionará como se esperaba se especificas bool como 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))
Executar este ficheiro desde a liña de comandos.
$ python argparse_type_bool.py True
True
<type 'bool'>
Se se usa true como argumento, lerase como un tipo bool true. Este é o comportamento esperado, pero o problema é o seguinte caso.
$ python argparse_type_bool.py False
True
<type 'bool'>
$ python argparse_type_bool.py bar
True
<type 'bool'>
Se usas false ou calquera outra cadea como argumento, lerase como verdadeiro.
O motivo polo que isto ocorre é que cando se especifica type=xxx en add_argument(), o argumento pásase a xxx().
Por exemplo, se type=int, o argumento pasarase a int(); se type=float, entón float().
O mesmo ocorre con type=bool, o que significa que o argumento pasará a bool().
Xuízo 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 considéranse falsos:
- None
- false
- Cero en tipos numéricos. Por exemplo, os seguintes valores
- 0
- 0
- 0j
- Unha secuencia baleira. Por exemplo
- ‘
- ()
- []
- Mapeo baleiro. Por exemplo
- {}
Suponse que todos os demais valores son verdadeiros; polo tanto, os obxectos de moitos tipos son sempre verdadeiros. As operacións e funcións integradas que devolven resultados booleanos sempre devolven 0 ou False como valor falso e 1 ou True como verdadeiro, a non ser que se indique o contrario.
Polo tanto, todas as cadeas non baleiras pasadas a bool(), xa sexan “true” ou “false”, devolverán true. Só as cadeas baleiras serán falsas.
print(bool('True'))
print(bool('False'))
print(bool('abc'))
# True
# True
# True
print(bool(''))
# False
Cando se establece type=bool en add_argument(), o argumento pásase a bool(). Polo tanto, como se mostra no exemplo anterior, se se usa false como argumento, bool() converterase como cadea ‘False’ e lerase como verdadeiro.
Use a acción de argumento en lugar do tipo de argumento.
Se queres usar valores booleanos en argparse, especifique ‘store_true’ ou ‘store_false’ para a acción do argumento.
- store_true’
- store_false’
Estas serán versións especiais de ‘store_const’ que almacenarán True e False respectivamente. Ademais, establecerán os valores predeterminados en False e True respectivamente, nesa orde.
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, ofrécense as seguintes opcións.--en
Polo tanto, se en non se define como verdadeiro, cargarase como falso, que é o valor predeterminado de en.
$ python argparse_option_bool.py --en
True
<type 'bool'>
$ python argparse_option_bool.py
False
<type 'bool'>
Se queres establecer o valor predeterminado como verdadeiro e falso cando se engade a opción, fai o seguinte.action='store_false'
Usando a función strtobool().
Se queres usar argumentos posicionais en lugar de opcións, tamén podes usar a función strtobool().
strtobool() é unha función que converte unha cadea en verdadeiro (1) ou falso (0).
Converte unha cadea booleana en verdadeiro (1) ou falso (0).
Os verdadeiros valores son os seguintes
y
yes
true
on
1
Os valores falsos son os seguintes.
n
no
f
false
off
0
Se val non é ningunha das anteriores, xera ValueError.
9. API Reference – strtobool() — Python 3.10.0 Documentation
Non distingue entre maiúsculas e minúsculas, polo que, por exemplo, pode usar o seguinte; calquera outra cadea producirá un 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(), pero o valor de retorno non é bool, senón int (1 ou 0).
print(type(strtobool('true')))
# <class 'int'>
Como se escribiu anteriormente, cando se especifica type=xxx en add_argument() de argparse, o argumento pasarase a xxx(). Polo tanto, podemos facer 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 non é un tipo bool, senón un tipo int 1 ou 0, pero pode ler valores verdadeiros ou falsos con true ou false como argumentos.
$ python argparse_type_strtobool.py true
1
<type 'int'>
$ python argparse_type_strtobool.py false
0
<type 'int'>
Ademais, se non se espera o argumento, xerarase un erro correctamente.
$ 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'