Budite oprezni kada radite s Booleovim vrijednostima u Pythonovom argparseu

Poslovanje

Za rukovanje argumentima naredbenog retka u Pythonu, koristite module argv ili argparse modula sys.

Modul argparse omogućuje fleksibilno rukovanje argumentima naredbenog retka, ali treba biti oprezan kada se radi s Booleovim vrijednostima (true, false).

Ovdje su navedene sljedeće informacije.

  • argparse za jednostavnu definiciju argumenata
  • Navedite tip argumenta (tip) pomoću argparse
  • Nemojte navoditi “bool” kao tip argumenta add_argument()
  • Sud prema bool()
  • Upotrijebite akciju argumenta umjesto tipa argumenta.
  • Korištenje funkcije strtobool().

argparse za jednostavnu definiciju argumenata

Modul argparse olakšava definiranje argumenata naredbenog retka.

Modul argparse olakšava kreiranje sučelja naredbenog retka prilagođenog korisniku. Vi definirate koje argumente vaš program treba, a argparse će shvatiti kako raščlaniti te opcije iz sys.argv. argparse modul automatski generira poruke pomoći i upotrebe te pokreće pogrešku ako korisnik navede nevažeće argumente programu. greška kada korisnik navede nevažeće argumente programu.
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation

Navedite tip argumenta (tip) pomoću argparse

Korisna značajka argparsea je specificiranje tipa (vrste).

Na primjer, ako navedete cjelobrojni (int) tip, on će automatski pretvoriti argument u int i također pokrenuti pogrešku za argumente koji nisu int.

Tip je specificiran tipom argumenta 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))

Pokrenite ovu datoteku iz naredbenog retka.

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

Argument 100 čita se kao int.

Ako se kao argument koristi vrijednost koja nije int, pojavit će se pogreška.

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

Vrlo korisno za igranje neočekivanih rasprava.

Nemojte navoditi “bool” kao tip argumenta add_argument()

Važno je napomenuti da bool, poput int i float, neće raditi kako se očekuje ako navedete bool kao tip argumenta 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))

Pokrenite ovu datoteku iz naredbenog retka.

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

Ako se true koristi kao argument, čitat će se kao bool tip true. Ovo je očekivano ponašanje, ali problem je u sljedećem slučaju.

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

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

Ako koristite false ili bilo koji drugi niz kao argument, on će se čitati kao istinit.

Razlog zašto se to događa je taj što kada je type=xxx specificiran u add_argument(), argument se prosljeđuje xxx().

Na primjer, ako je type=int, argument će biti proslijeđen int(); ako je type=float, onda float().

Isto vrijedi i za type=bool, što znači da će argument biti proslijeđen bool().

Sud prema bool()

Ovaj bool() je lukav.

Sljedeće vrijednosti smatraju se netočnim:

  • None
  • false
  • Nula u brojčanim tipovima. Na primjer, sljedeće vrijednosti
    • 0
    • 0
    • 0j
  • Prazan niz. Na primjer
    • ()
    • []
  • Prazno mapiranje. Na primjer
    • {}

Pretpostavlja se da su sve ostale vrijednosti istinite – stoga su objekti mnogih tipova uvijek istiniti. Operacije i ugrađene funkcije koje vraćaju Booleove rezultate uvijek vraćaju 0 ili False kao netočnu vrijednost i 1 ili True kao istinitu vrijednost, osim ako nije drugačije navedeno.

Stoga će svi neprazni nizovi proslijeđeni bool(), bez obzira jesu li ‘true’ ili ‘false’, vratiti true. Samo će prazni nizovi biti lažni.

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

print(bool(''))
# False

Kada je type=bool postavljen u add_argument(), argument se prosljeđuje bool(). Stoga, kao što je prikazano u gornjem primjeru, ako se false koristi kao argument, on će biti konvertiran pomoću bool() kao niz ‘False’ i pročitan kao true.

Upotrijebite akciju argumenta umjesto tipa argumenta.

Ako želite koristiti Booleove vrijednosti u argparseu, navedite ‘store_true’ ili ‘store_false’ za akciju argumenta.

  • store_true’
  • store_false’

To će biti posebne verzije ‘store_const’ koje će pohraniti True i False. Osim toga, postavit će zadane vrijednosti na False i True, tim redoslijedom.
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))

U ovom primjeru dane su sljedeće opcije.
--enStoga, ako en nije postavljen kao istinit, bit će učitan kao lažan, što je zadana vrijednost en.

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

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

Ako želite postaviti zadanu vrijednost na true i false kada je opcija dodana, samo učinite sljedeće.
action='store_false'

Korištenje funkcije strtobool().

Ako želite koristiti pozicijske argumente umjesto opcija, možete koristiti i funkciju strtobool().

strtobool() je funkcija koja pretvara niz u true (1) ili false (0).

Pretvara logički niz u true (1) ili false (0).
Prave vrijednosti su sljedeće

  • y
  • yes
  • true
  • on
  • 1

Lažne vrijednosti su sljedeće.

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

Ako val nije ništa od gore navedenog, podiže ValueError.

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

Nije osjetljivo na velika i mala slova, pa na primjer, možete koristiti sljedeće; bilo koji drugi niz rezultirat će pogreškom.

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

Ime je strtobool(), ali povratna vrijednost nije bool, već int (1 ili 0).

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

Kao što je ranije napisano, kada je type=xxx specificiran u add_argument() argparsea, argument će biti proslijeđen xxx(). Stoga možemo učiniti sljedeće.
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))

Povratna vrijednost nije bool tip, već int tip 1 ili 0, ali može čitati istinite ili lažne vrijednosti s true ili false kao argumentima.

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

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

Također, ako se argument ne očekuje, pogreška će se ispravno generirati.

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