Для обработки аргументов командной строки в Python используйте модули argv или argparse модуля sys.
Модуль argparse позволяет гибко работать с аргументами командной строки, но при работе с булевыми значениями (true, false) необходимо соблюдать осторожность.
Здесь представлена следующая информация.
- 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 является указание типа (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, он будет прочитан как true типа bool. Это ожидаемое поведение, но проблема заключается в следующем случае.
$ python argparse_type_bool.py False
True
<type 'bool'>
$ python argparse_type_bool.py bar
True
<type 'bool'>
Если вы используете false или любую другую строку в качестве аргумента, она будет считана как true.
Это происходит потому, что когда type=xxx указан в add_argument(), аргумент передается в 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. Только пустые строки будут ложными.
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'