Fiți atenți când aveți de-a face cu valori booleene în argparse din Python

Afaceri

Pentru a gestiona argumentele liniei de comandă în Python, utilizați modulele argv sau argparse din modulul sys.

Modulul argparse permite o gestionare flexibilă a argumentelor din linia de comandă, dar trebuie să se acorde atenție atunci când se utilizează valori booleene (true, false).

Aici sunt furnizate următoarele informații.

  • argparse pentru definirea ușoară a argumentelor
  • Specificați tipul argumentului (type) cu argparse
  • Nu specificați „bool” ca tip de argument pentru add_argument()
  • Judecata prin bool()
  • Utilizați acțiunea argumentului în locul tipului de argument.
  • Utilizarea funcției strtobool()

argparse pentru definirea ușoară a argumentelor

Modulul argparse facilitează definirea argumentelor din linia de comandă.

Modulul argparse facilitează crearea unor interfețe de linie de comandă ușor de utilizat. Dumneavoastră definiți de ce argumente are nevoie programul dumneavoastră, iar argparse își va da seama cum să analizeze aceste opțiuni din sys.argv. modulul argparse generează automat mesaje de ajutor și de utilizare și ridică o eroare dacă utilizatorul specifică argumente invalide pentru program. error when the user specifies invalid arguments to the program. eroare atunci când utilizatorul specifică argumente invalide pentru program.
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation

Specificați tipul argumentului (type) cu argparse

O caracteristică utilă a argparse este aceea de a specifica tipul (type).

De exemplu, dacă specificați un tip întreg (int), acesta va converti automat argumentul în int și, de asemenea, va genera o eroare pentru argumentele care nu sunt int.

Tipul este specificat de tipul de argument din 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))

Rulați acest fișier din linia de comandă.

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

Argumentul 100 este citit ca int.

În cazul în care se utilizează ca argument o valoare care nu este un intens, se va produce o eroare.

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

Foarte util pentru a reda argumente neașteptate.

Nu specificați „bool” ca tip de argument pentru add_argument()

Este important de reținut că bool, ca și int și float, nu va funcționa conform așteptărilor dacă specificați bool ca tip de argument pentru 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))

Rulați acest fișier din linia de comandă.

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

Dacă true este utilizat ca argument, acesta va fi citit ca un bool de tip true. Acesta este comportamentul așteptat, dar problema este reprezentată de următorul caz.

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

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

Dacă utilizați false sau orice alt șir de caractere ca argument, acesta va fi citit ca fiind adevărat.

Motivul pentru care se întâmplă acest lucru este că, atunci când tipul=xxx este specificat în add_argument(), argumentul este transmis la xxx().

De exemplu, dacă tipul=int, argumentul va fi transmis la int(); dacă tipul=float, atunci float().

Același lucru este valabil și pentru type=bool, ceea ce înseamnă că argumentul va fi transmis la bool().

Judecata prin bool()

Acest bool() este unul dificil.

Următoarele valori sunt considerate false:

  • None
  • false
  • Zero în tipurile numerice. De exemplu, următoarele valori
    • 0
    • 0.0
    • 0j
  • O secvență goală. De exemplu
    • ''
    • ()
    • []
  • Cartografiere goală. De exemplu
    • {}

Toate celelalte valori sunt presupuse a fi adevărate – astfel, obiectele de multe tipuri sunt întotdeauna adevărate. Operațiile și funcțiile încorporate care returnează rezultate booleene returnează întotdeauna 0 sau False ca valoare falsă și 1 sau True ca valoare adevărată, cu excepția cazului în care se specifică altfel.

Prin urmare, toate șirurile de caractere care nu sunt goale transmise la bool(), indiferent dacă sunt „true” sau „false”, vor returna true. Numai șirurile goale vor fi false.

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

print(bool(''))
# False

Atunci când tipul=bool este setat în add_argument(), argumentul este transmis la bool(). Prin urmare, după cum se arată în exemplul de mai sus, dacă se utilizează false ca argument, acesta va fi convertit de bool() ca șirul de caractere „False” și va fi citit ca true.

Utilizați acțiunea argumentului în locul tipului de argument.

Dacă doriți să utilizați valori booleene în argparse, specificați „store_true” sau „store_false” pentru acțiunea argumentului.

  • 'store_true'
  • 'store_false'

Acestea vor fi versiuni speciale ale „store_const” care vor stoca True și respectiv False. În plus, acestea vor seta valorile implicite la False și, respectiv, True, în această ordine.
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))

În acest exemplu, sunt oferite următoarele opțiuni.
--enPrin urmare, dacă en nu este setat ca fiind adevărat, va fi încărcat ca fiind fals, care este valoarea implicită a lui en.

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

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

Dacă doriți să setați valoarea implicită la true și la false atunci când opțiunea este adăugată, procedați după cum urmează.
action='store_false'

Utilizarea funcției strtobool()

Dacă doriți să utilizați argumente poziționale în loc de opțiuni, puteți utiliza, de asemenea, funcția strtobool().

strtobool() este o funcție care convertește un șir de caractere în adevărat (1) sau fals (0).

Convertește un șir boolean în true (1) sau false (0).
Valorile reale sunt următoarele

  • y
  • yes
  • true
  • on
  • 1

Valorile false sunt după cum urmează.

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

Dacă val nu este niciuna dintre cele de mai sus, se ridică ValueError.

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

Nu face distincție între majuscule și minuscule, așa că, de exemplu, puteți utiliza următorul text; orice alt șir de caractere va duce la o eroare.

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

Numele este strtobool(), dar valoarea de returnare nu este bool, ci int (1 sau 0).

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

După cum s-a scris mai devreme, atunci când tipul=xxx este specificat în add_argument() din argparse, argumentul va fi transmis la xxx(). Prin urmare, putem face următoarele.
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))

Valoarea de returnare nu este de tip bool, ci de tip int 1 sau 0, dar poate citi valorile true sau false cu true sau false ca argumente.

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

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

De asemenea, în cazul în care argumentul nu este așteptat, va fi generată o eroare în mod corespunzător.

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