Будзьце ўважлівыя пры працы з булевымі значэннямі ў argparse Python

Бізнэс

Для апрацоўкі аргументаў каманднага радка ў Python выкарыстоўвайце модулі argv або argparse модуля sys.

Модуль argparse дазваляе гнутка апрацоўваць аргументы каманднага радка, але пры працы з булевымі значэннямі (праўда, ілжыва) трэба быць асцярожнымі.

Тут прадстаўлена наступная інфармацыя.

  • argparse для лёгкага вызначэння аргументаў
  • Пакажыце тып аргументу (тып) з дапамогай argparse
  • Не ўказвайце “bool” як тып аргументу add_argument()
  • Прысуд па bool()
  • Выкарыстоўвайце дзеянне аргумента замест тыпу аргумента.
  • Выкарыстанне функцыі strtobool().

argparse для лёгкага вызначэння аргументаў

Модуль argparse дазваляе лёгка вызначаць аргументы каманднага радка.

Модуль argparse дазваляе лёгка ствараць зручныя інтэрфейсы каманднага радка. Вы вызначаеце, якія аргументы патрэбны вашай праграме, і argparse высветліць, як разабраць гэтыя параметры з sys.argv. Модуль argparse аўтаматычна генеруе даведку і паведамленні аб выкарыстанні, а таксама выклікае памылку, калі карыстальнік паказвае несапраўдныя аргументы для праграмы. памылка, калі карыстальнік паказвае несапраўдныя аргументы праграме.
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation

Пакажыце тып аргументу (тып) з дапамогай argparse

Карыснай асаблівасцю argparse з’яўляецца ўказанне тыпу (тыпу).

Напрыклад, калі вы задасце цэлы тып (int), ён аўтаматычна пераўтворыць аргумент у int, а таксама выкліча памылку для аргументаў, якія не з’яўляюцца int.

Тып вызначаецца тыпам аргументу 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))

Запусціце гэты файл з каманднага радка.

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

Аргумент 100 чытаецца як унутр.

Калі ў якасці аргументу выкарыстоўваецца значэнне, якое не з’яўляецца INT, адбудзецца памылка.

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

Вельмі карысна для разыгрывання нечаканых аргументаў.

Не ўказвайце “bool” як тып аргументу add_argument()

Важна адзначыць, што bool, як int і float, не будзе працаваць так, як чакалася, калі вы пакажаце bool як тып аргументу 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))

Запусціце гэты файл з каманднага радка.

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

Калі ў якасці аргумента выкарыстоўваецца true, ён будзе прачытаны як логічны тып true. Гэта чаканыя паводзіны, але праблема заключаецца ў наступным выпадку.

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

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

Калі вы выкарыстоўваеце ў якасці аргумента false або любы іншы радок, ён будзе прачытаны як ісціна.

Прычына, чаму гэта адбываецца, заключаецца ў тым, што калі ў add_argument() зададзены тып=xxx), аргумент перадаецца ў xxx().

Напрыклад, калі type=int, аргумент будзе перададзены ў int(); калі type=float, то float().

Тое ж самае дакладна і для type=bool, што азначае, што аргумент будзе перададзены ў bool().

Прысуд па bool()

Гэты bool() з’яўляецца складаным.

Наступныя значэнні лічацца ілжывымі:

  • None
  • false
  • Нуль у лікавых тыпах. Напрыклад, наступныя значэнні
    • 0
    • 0
    • 0j
  • Пустая паслядоўнасць. Напрыклад
    • ()
    • []
  • Пустае адлюстраванне. Напрыклад
    • {}

Усе астатнія значэнні прымаюцца за праўдзівыя – такім чынам, аб’екты многіх тыпаў заўсёды праўдзівыя. Аперацыі і ўбудаваныя функцыі, якія вяртаюць лагічныя вынікі, заўсёды вяртаюць 0 або False у якасці ілжывага значэння і 1 або True як праўдзівага значэння, калі не пазначана іншае.

Такім чынам, усе непустыя радкі, перададзеныя ў bool(), няхай гэта будзе “праўда” або “хлусня”, будуць вяртаць праўду. Толькі пустыя радкі будуць ілжывымі.

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

print(bool(''))
# False

Калі type=bool усталяваны ў add_argument(), аргумент перадаецца ў bool(). Такім чынам, як паказана ў прыведзеным вышэй прыкладзе, калі ў якасці аргумента выкарыстоўваецца false, ён будзе ператвораны bool() у радок ‘False’ і прачытаны як ісціна.

Выкарыстоўвайце дзеянне аргумента замест тыпу аргумента.

Калі вы хочаце выкарыстоўваць лагічныя значэнні ў argparse, укажыце ‘store_true’ або ‘store_false’ для дзеяння аргумента.

  • store_true’
  • store_false’

Гэта будуць спецыяльныя версіі ‘store_const’, якія будуць захоўваць True і False адпаведна. Акрамя таго, яны ўсталююць значэнні па змаўчанні ў False і True адпаведна ў такім парадку.
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Такім чынам, калі en не зададзены як ісціна, ён будзе загружаны як false, што з’яўляецца значэннем en па змаўчанні.

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

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

Калі вы хочаце ўсталяваць па змаўчанні значэнне ісціна і false пры даданні опцыі, проста зрабіце наступнае.
action='store_false'

Выкарыстанне функцыі strtobool().

Калі вы хочаце выкарыстоўваць пазіцыйныя аргументы замест опцый, вы таксама можаце выкарыстоўваць функцыю strtobool().

strtobool() – гэта функцыя, якая пераўтворыць радок у праўдзівы (1) або ілжывы (0).

Пераўтварае лагічны радок у праўдзівы (1) або ілжывы (0).
Сапраўдныя значэнні наступныя

  • y
  • yes
  • true
  • on
  • 1

Ілжывыя значэнні наступныя.

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

Калі val не з’яўляецца адным з вышэйпералічаных, ён выклікае ValueError.

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

Ён не адчувальны да рэгістра, таму, напрыклад, вы можаце выкарыстоўваць наступнае; любая іншая радок прывядзе да памылкі.

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

Імя – strtobool(), але вяртае значэнне не bool, а int (1 або 0).

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

Як пісалася раней, калі type=xxx зададзены ў add_argument() argparse, аргумент будзе перададзены xxx(). Такім чынам, мы можам зрабіць наступнае.
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))

Значэнне, якое вяртаецца, не з’яўляецца буйным тыпам, а тыпам int 1 або 0, але яно можа чытаць значэнні праўдзіва або ілжыва з аргументамі true або false.

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

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

Акрамя таго, калі аргумент не чакаецца, памылка будзе створана правільна.

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