要在 Python 中处理命令行参数,可以使用 sys 模块的 argv 或 argparse 模块。
argparse模块允许灵活地处理命令行参数,但在处理布尔值(true, false)时必须注意。
这里提供了以下信息。
- argparse,便于定义参数
- 用argparse指定参数的类型(type)。
- 不要指定 “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指定参数的类型(type)。
argparse的一个有用的功能是指定类型(type)。
例如,如果你指定一个整数(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。
如果使用一个非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作为add_argument()的参数类型,bool和int、float一样,不会像预期那样工作。
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。
出现这种情况的原因是,当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()的非空字符串,无论是 “真 “还是 “假”,都将返回真。只有空字符串将是假的。
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没有被设置为真,它将被加载为假,这是en的默认值。
$ python argparse_option_bool.py --en
True
<type 'bool'>
$ python argparse_option_bool.py
False
<type 'bool'>
如果你想把默认值设置为 “真”,而在添加选项时设置为 “假”,只需做以下工作。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'>
正如前面所写,当在argparse的add_argument()中指定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作为参数读取真假值。
$ 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'