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.--enPolo 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
yyestrueon1Os valores falsos son os seguintes.
nnoffalseoff0Se 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'