Bodite previdni pri ravnanju z logičnimi vrednostmi v Pythonovem argparse

Posel

Za obdelavo argumentov ukazne vrstice v Pythonu uporabite modula argv ali argparse modula sys.

Modul argparse omogoča prilagodljivo ravnanje z argumenti ukazne vrstice, vendar je treba biti previden pri ravnanju z logičnimi vrednostmi (true, false).

Tu so na voljo naslednje informacije.

  • argparse za enostavno definicijo argumentov
  • Določite vrsto argumenta (type) z argparse
  • Ne navedite “bool” kot vrsto argumenta v funkciji add_argument()
  • Sodba z bool()
  • Namesto vrste argumenta uporabite dejanje argumenta.
  • Uporaba funkcije strtobool()

argparse za enostavno definicijo argumentov

Modul argparse omogoča enostavno določanje argumentov ukazne vrstice.

Modul argparse omogoča enostavno ustvarjanje uporabniku prijaznih vmesnikov ukazne vrstice. Določite, katere argumente potrebuje vaš program, modul argparse pa bo ugotovil, kako te možnosti razčleniti iz sys.argv. modul argparse samodejno generira sporočila za pomoč in uporabo ter sproži napako, če uporabnik programu določi neveljavne argumente. error when the user specifies invalid arguments to the program.
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation

Določite vrsto argumenta (type) z argparse

Koristna funkcija argparse je določanje tipa (type).

Če na primer določite vrsto celega števila (int), se argument samodejno pretvori v int in se pri argumentih, ki niso int, sproži napaka.

Tip je določen s tipom argumenta funkcije 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))

To datoteko zaženite iz ukazne vrstice.

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

Argument 100 se prebere kot int.

Če je kot argument uporabljena vrednost, ki ni int, pride do napake.

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

Zelo uporabno za igranje nepričakovanih argumentov.

Ne navedite “bool” kot vrsto argumenta v funkciji add_argument()

Pomembno je opozoriti, da bool, tako kot int in float, ne bo deloval v skladu s pričakovanji, če kot tip argumenta v funkciji add_argument() navedete bool.

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))

To datoteko zaženite iz ukazne vrstice.

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

Če je kot argument uporabljen true, se prebere kot tip bool true. To je pričakovano obnašanje, vendar je težava v naslednjem primeru.

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

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

Če kot argument uporabite false ali kateri koli drug niz, se bo prebral kot true.

Razlog za to je, da se ob vnosu type=xxx v funkcijo add_argument() argument posreduje funkciji xxx().

Na primer, če je tip=int, bo argument posredovan funkciji int(); če je tip=float, pa funkciji float().

Enako velja za type=bool, kar pomeni, da bo argument posredovan funkciji bool().

Sodba z bool()

Ta funkcija bool() je zapletena.

Naslednje vrednosti se štejejo za napačne:

  • None
  • false
  • Nula v številskih vrstah. Na primer naslednje vrednosti
    • 0
    • 0.0
    • 0j
  • Prazno zaporedje. Na primer
    • ''
    • ()
    • []
  • Prazno kartiranje. Na primer
    • {}

Za vse druge vrednosti se predpostavlja, da so resnične – tako so predmeti številnih vrst vedno resnični. Operacije in vgrajene funkcije, ki vračajo logične rezultate, vedno vračajo 0 ali False kot lažno vrednost in 1 ali True kot resnično vrednost, razen če ni drugače navedeno.

Zato bodo vsi neprazni nizi, posredovani funkciji bool(), bodisi 'true' bodisi 'false', vrnili true. Samo prazni nizi bodo false.

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

print(bool(''))
# False

Če je v funkciji add_argument() nastavljeno type=bool, se argument posreduje funkciji bool(). Zato bo, kot je prikazano v zgornjem primeru, če je kot argument uporabljen false, ga bool() pretvoril v niz 'False' in prebral kot true.

Namesto vrste argumenta uporabite dejanje argumenta.

Če želite v argparse uporabiti logične vrednosti, določite 'store_true' ali 'store_false' za dejanje argumenta.

  • 'store_true'
  • 'store_false'

To bodo posebne različice 'store_const', ki bodo shranjevale True oziroma False. Poleg tega bodo privzete vrednosti nastavili na False oziroma True v tem vrstnem redu.
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))

V tem primeru so podane naslednje možnosti.
--enČe en ni nastavljen kot true, se naloži kot false, kar je privzeta vrednost en.

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

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

Če želite nastaviti privzeto vrednost na true in false, ko je možnost dodana, naredite naslednje.
action='store_false'

Uporaba funkcije strtobool()

Če želite namesto možnosti uporabiti pozicijske argumente, lahko uporabite tudi funkcijo strtobool().

strtobool() je funkcija, ki pretvori niz v true (1) ali false (0).

pretvori logični niz v true (1) ali false (0).
Resnične vrednosti so naslednje

  • y
  • yes
  • true
  • on
  • 1

Lažne vrednosti so naslednje.

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

Če val ni nobena od zgornjih vrednosti, se sproži ValueError.

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

Ne razlikuje velikih in malih črk, zato lahko na primer uporabite naslednji niz; vsak drug niz bo povzročil napako.

  • '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(), vendar vrnjena vrednost ni bool, temveč int (1 ali 0).

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

Kot je bilo zapisano prej, če je v funkciji add_argument() funkcije argparse navedeno type=xxx, bo argument posredovan funkciji xxx(). Zato lahko naredimo naslednje.
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 vrednost ni tipa bool, temveč tipa int 1 ali 0, vendar lahko prebere vrednosti true ali false, če sta argumenta true ali false.

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

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

Če argument ni pričakovan, se pravilno ustvari napaka.

$ 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