За обработка на аргументи от командния ред в Python използвайте модулите argv или argparse на модула sys.
Модулът argparse позволява гъвкава обработка на аргументи от командния ред, но трябва да се внимава при работа с булеви стойности (true, false).
Тук се предоставя следната информация.
- argparse за лесно дефиниране на аргументи
- Определяне на типа на аргумента (type) с 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
Определяне на типа на аргумента (type) с argparse
Полезна функция на argparse е задаването на типа (type).
Например, ако посочите тип integer (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, той ще бъде прочетен като тип bool true. Това е очакваното поведение, но проблемът е в следния случай.
$ python argparse_type_bool.py False
True
<type 'bool'>
$ python argparse_type_bool.py bar
True
<type 'bool'>
Ако използвате false или друг низ като аргумент, той ще бъде прочетен като true.
Причината за това е, че когато в add_argument() е зададен type=xxx, аргументът се предава на xxx().
Например, ако type=int, аргументът ще бъде предаден на int(); ако type=float, тогава на float().
Същото важи и за type=bool, което означава, че аргументът ще бъде предаден на функцията bool().
Преценка от bool()
Тази функция bool() е трудна.
- bool() — Built-in Functions — Python 3.10.0 Documentation
- Truth Value Testing — Built-in Types — Python 3.10.0 Documentation
Следните стойности се считат за неверни:
- None
- false
- Нула в числовите типове. Например следните стойности
- 0
- 0.0
- 0j
- Празна последователност. Например
- ''
- ()
- []
- Празно картографиране. Например
- {}
Всички останали стойности се приемат за истинни – по този начин обектите от много типове са винаги истинни. Операциите и вградените функции, които връщат булеви резултати, винаги връщат 0 или False като невярна стойност и 1 или True като вярна стойност, освен ако не е посочено друго.
Следователно всички непразни низове, подадени на функцията bool(), независимо дали са 'true' или 'false', ще връщат true. Само празните низове ще бъдат false.
print(bool('True'))
print(bool('False'))
print(bool('abc'))
# True
# True
# True
print(bool(''))
# False
Когато в add_argument() е зададено type=bool, аргументът се предава на bool(). Следователно, както е показано в примера по-горе, ако като аргумент се използва false, той ще бъде преобразуван от bool() като низ 'False' и прочетен като true.
Използвайте действието на аргумента вместо типа на аргумента.
Ако искате да използвате булеви стойности в 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 не е зададен като true, той ще бъде зареден като false, което е стойността по подразбиране на en.
$ python argparse_option_bool.py --en
True
<type 'bool'>
$ python argparse_option_bool.py
False
<type 'bool'>
Ако искате да зададете по подразбиране стойност true, а при добавяне на опцията – false, просто направете следното.action='store_false'
Използване на функцията strtobool()
Ако искате да използвате позиционни аргументи вместо опции, можете да използвате и функцията strtobool().
strtobool() е функция, която преобразува низ в true (1) или false (0).
Преобразува булев низ в true (1) или false (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'>
Както беше написано по-рано, когато в add_argument() на argparse е посочен type=xxx, аргументът ще бъде предаден на 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))
Върнатата стойност не е тип bool, а тип int 1 или 0, но може да чете стойности true или false с 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'