Aneu amb compte quan tracteu valors booleans a l’argparse de Python

Negocis

Per gestionar els arguments de la línia d’ordres a Python, utilitzeu els mòduls argv o argparse del mòdul sys.

El mòdul argparse permet un maneig flexible dels arguments de la línia d’ordres, però cal tenir cura quan es tracten valors booleans (true, false).

La informació següent es proporciona aquí.

  • argparse per definir fàcilment els arguments
  • Especifiqueu el tipus d’argument (tipus) amb argparse
  • No especifiqueu “bool” com a tipus d’argument de add_argument()
  • Judici per bool()
  • Utilitzeu l’acció d’argument en lloc del tipus d’argument.
  • Utilitzant la funció strtobool().

argparse per definir fàcilment els arguments

El mòdul argparse facilita la definició d’arguments de línia d’ordres.

El mòdul argparse facilita la creació d’interfícies de línia d’ordres fàcils d’utilitzar. Definiu quins arguments necessita el vostre programa i argparse descobrirà com analitzar aquestes opcions des de sys.argv. El mòdul argparse genera automàticament missatges d’ajuda i ús, i genera un error si l’usuari especifica arguments no vàlids al programa. error quan l’usuari especifica arguments no vàlids al programa.
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation

Especifiqueu el tipus d’argument (tipus) amb argparse

Una característica útil d’argparse és especificar el tipus (tipus).

Per exemple, si especifiqueu un tipus d’enter (int), convertirà automàticament l’argument a int i també generarà un error per als arguments que no siguin int.

El tipus s’especifica mitjançant el tipus d’argument 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))

Executeu aquest fitxer des de la línia d’ordres.

$ python argparse_type_int.py 100
100
<type 'int'>

L’argument 100 es llegeix com int.

Si s’utilitza un valor no int com a argument, es produirà un error.

$ 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'

Molt útil per jugar arguments inesperats.

No especifiqueu “bool” com a tipus d’argument de add_argument()

És important tenir en compte que bool, com int i float, no funcionarà com s’esperava si especifiqueu bool com a tipus d’argument d’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))

Executeu aquest fitxer des de la línia d’ordres.

$ python argparse_type_bool.py True
True
<type 'bool'>

Si s’utilitza true com a argument, es llegirà com un tipus bool true. Aquest és el comportament esperat, però el problema és el cas següent.

$ python argparse_type_bool.py False
True
<type 'bool'>

$ python argparse_type_bool.py bar
True
<type 'bool'>

Si utilitzeu false o qualsevol altra cadena com a argument, es llegirà com a vertader.

El motiu pel qual això passa és que quan s’especifica type=xxx a add_argument(), l’argument es passa a xxx().

Per exemple, si type=int, l’argument es passarà a int(); si type=float, llavors float().

El mateix passa amb type=bool, el que significa que l’argument es passarà a bool().

Judici per bool()

Aquest bool() és complicat.

Els valors següents es consideren falsos:

  • None
  • false
  • Zero en tipus numèrics. Per exemple, els valors següents
    • 0
    • 0
    • 0j
  • Una seqüència buida. Per exemple
    • ()
    • []
  • Mapatge buit. Per exemple
    • {}

Se suposa que tots els altres valors són certs; per tant, els objectes de molts tipus sempre són certs. Les operacions i les funcions integrades que retornen resultats booleans sempre retornen 0 o Fals com a valor fals i 1 o True com a valor vertader, tret que s’indiqui el contrari.

Per tant, totes les cadenes no buides passades a bool(), ja siguin “true” o “false”, retornaran true. Només les cadenes buides seran falses.

print(bool('True'))
print(bool('False'))
print(bool('abc'))
# True
# True
# True

print(bool(''))
# False

Quan s’estableix type=bool a add_argument(), l’argument es passa a bool(). Per tant, com es mostra a l’exemple anterior, si s’utilitza false com a argument, es convertirà per bool() com a cadena ‘False’ i es llegirà com a vertader.

Utilitzeu l’acció d’argument en lloc del tipus d’argument.

Si voleu utilitzar valors booleans a argparse, especifiqueu “store_true” o “store_false” per a l’acció de l’argument.

  • store_true’
  • store_false’

Aquestes seran versions especials de ‘store_const’ que emmagatzemaran True i False respectivament. A més, establiran els valors per defecte a Fals i True respectivament, en aquest ordre.
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))

En aquest exemple, es donen les opcions següents.
--enPer tant, si en no s’estableix com a true, es carregarà com a fals, que és el valor per defecte de en.

$ python argparse_option_bool.py --en
True
<type 'bool'>

$ python argparse_option_bool.py
False
<type 'bool'>

Si voleu establir el valor predeterminat com a true i false quan s’afegeix l’opció, feu el següent.
action='store_false'

Utilitzant la funció strtobool().

Si voleu utilitzar arguments posicionals en lloc d’opcions, també podeu utilitzar la funció strtobool().

strtobool() és una funció que converteix una cadena en vertader (1) o fals (0).

Converteix una cadena booleana en vertader (1) o fals (0).
Els valors reals són els següents

  • y
  • yes
  • true
  • on
  • 1

Els valors falsos són els següents.

  • n
  • no
  • f
  • false
  • off
  • 0

Si val no és cap de les anteriors, genera ValueError.

9. API Reference – strtobool() — Python 3.10.0 Documentation

No distingeix entre majúscules i minúscules, per tant, per exemple, podeu utilitzar el següent; qualsevol altra cadena donarà lloc a un error.

  • 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'

El nom és strtobool(), però el valor de retorn no és bool, sinó int (1 o 0).

print(type(strtobool('true')))
# <class 'int'>

Com s’ha escrit anteriorment, quan s’especifica type=xxx a add_argument() d’argparse, l’argument es passarà a xxx(). Per tant, podem fer el següent.
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))

El valor de retorn no és un tipus bool, sinó un tipus int 1 o 0, però pot llegir valors true o false amb true o false com a arguments.

$ python argparse_type_strtobool.py true
1
<type 'int'>

$ python argparse_type_strtobool.py false
0
<type 'int'>

A més, si no s’espera l’argument, es generarà un error correctament.

$ 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'
Copied title and URL