1 引言
argparse
模块是Python中用于解析命令行参数的标准模块。以下是使用argparse
定义基本命令行接口的一个例子,包括添加一些参数:
from argparse import ArgumentParser
# 创建解析器对象
parser = ArgumentParser(description='test argparse')
# 添加参数
parser.add_argument('-i', '--input', help='输入文件名', required=True)
parser.add_argument('-o', '--output', help='输出文件名', required=False)
parser.add_argument('-v', '--verbose', help='是否输出详细信息', action='store_true')
# 解析命令行参数
args = parser.parse_args()
# 使用解析后的参数
if args.verbose:
print("详细模式已启用")
if args.input:
print(f"输入文件:{args.input}")
if args.output:
print(f"输出文件:{args.output}")
在这个例子中:
- 使用
add_argument
方法来指定脚本接受命令行选项。这里-i
或--input
选项被标记为必需的,意味着如果没有提供这个选项,脚本将无法正常运行。-o
或--output
选项是可选的。 --verbose
标志是一种特殊类型的选项,当指定时,它会在args.verbose
中存储True
。parse_args
方法解析传递给脚本的命令行参数。例如脚本运行命令是python test.py -i example.txt -v
,那么args.input
将是example.txt
,并且args.verbose
将是True
。
2 ArgumentParser的原型
argparse.ArgumentParser
类用于构建命令行参数和选项的解析器。下面是它的基本原型和参数含义:
ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True, allow_abbrev=True)
参数含义
- prog: 程序的名称(默认值:
sys.argv[0]
)。它会在帮助消息中使用。 - usage: 描述程序用法的字符串(默认值:由
argparse
自动生成)。你可以提供一个自定义的用法描述字符串。 - description: 在帮助文档之前显示的文本(默认值:
None
)。这通常用于简短地描述程序做什么以及如何工作。 - epilog: 在帮助文档之后显示的文本(默认值:
None
)。这可以用来提供相关信息,比如如何使用输出等。 - parents: 一个
ArgumentParser
对象的列表,这些对象的参数也应包含在内(默认值:空列表)。这主要用于复用参数。 - formatter_class: 用于自定义帮助文档输出格式的类(默认值:
argparse.HelpFormatter
)。 - prefix_chars: 参数前缀字符(默认值:‘-’)。你可以更改它,如果你希望使用不同的前缀,例如
+
或/
等。 - fromfile_prefix_chars: 如果提供,则可以从文件中读取额外的参数(默认值:
None
)。 - argument_default: 设置一个全局参数默认值(默认值:
None
)。这是所有参数的全局默认值,除非它们已经定义了自己的默认值。 - conflict_handler: 解决参数名冲突的策略(默认值:‘error’)。当添加的参数名与现有参数冲突时,如何处理。
- add_help: 自动添加一个帮助选项(默认值:
True
)。通常是-h
/--help
,显示帮助信息。 - allow_abbrev: 如果为True,允许对长选项进行缩写,只要缩写是明确的(默认值:
True
)。
这些参数允许你自定义命令行解析器的行为,包括它如何显示帮助信息、如何处理参数和选项,以及如何解析它们。
3 add_argument的原型
add_argument
方法是ArgumentParser
对象的核心方法之一,用于向解析器添加命令行选项信息。每个选项都可以具有不同的行为,并由其参数进行控制。
add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
- name or flags: 参数名或选项字符串(如
-f
,--foo
)。位置参数会直接使用名字,而可选参数则通常使用-
或--
作为前缀。 - action: 定义了当参数在命令行中出现时应该采取的动作。常用的动作包括
store
(存储参数值,这是默认动作)、store_const
(存储被const
关键字参数指定的值)、store_true
/store_false
(分别存储True
/False
)、append
(存储一个列表,并将每个参数值追加到列表中)、count
(计算参数出现的次数)等。 - nargs: 参数应该消耗的命令行参数数量。它可以是一个整数或几个特殊字符,
'?'
表示一个参数,如果没有则为None
;'*'
表示所有参数到一个列表;'+'
表示所有,并且至少需要一个参数。 - const: 为一些
action
和nargs
选择提供常数值。 - default: 参数的默认值,如果命令行中未出现该参数,则使用此值。
- type: 参数应该被转换成的类型。默认情况下是字符串类型,但也可以是
int
、float
、complex
或任何接受单个字符串参数的函数。 - choices: 参数值允许的范围或集合。如果参数值不在指定的集合中,将会引发错误。
- required: 对于可选参数,这里可以指明该参数是否为必须(
True
/False
)。位置参数默认是必须的。 - help: 参数的帮助信息,当生成帮助文档时会显示。
- metavar: 在使用方法消息中代表该参数的字符串。主要用于帮助信息。
- dest: 被添加到解析参数返回对象上的属性名。默认情况下,对于可选参数,
dest
是长选项名去掉前缀--
,对于位置参数,dest
就是参数名。
3.1 name or flags
name or flags
是一个不定参数,意味着你可以传递一个或多个参数名或标志(flags)。例如:
# test.py
from argparse import ArgumentParser
# 初始化 ArgumentParser 对象
parser = ArgumentParser(description='[cqupt] 0.0.1 版本')
# 添加参数
parser.add_argument('-i', '--input', '--INPUT', help='输入文件名', required=True)
# 解析命令行参数
args = parser.parse_args()
if args.input:
print(f"输入文件: {args.input}")
在这个例子中,-i
、--input
和--INPUT
都引用同一个命令行参数,用户可以使用-i filename
、--input filename
或--input filename
来提供输入文件。
3.1.1 可选参数
可选参数通常是以-
或--
前缀定义,表示它们不是必须提供的。用户可以选择是否在命令行中提供这些参数,因此被称为可选参数。
特点
- 可以出现在命令行选项中的任何位置
- 有长格式(
--verbose
)和短格式(-v
),两种格式都可以使用。 - 可以有默认值,如果在命令行中未指定,将使用默认值。
- 可以使用
action
来定义当选项存在时应该执行的操作,如store_true
、store_false
等。
例如:
parser.add_argument('-v', '--verbose', action='store_true', help='Increase output verbosity')
3.1.2 位置参数
位置参数是在命令行中没有前缀,并且位置固定的参数。它们是必须提供的参数,其顺序在命令行中很重要。
特点
- 必须按照定义它们的顺序提供。
- 不需要前缀,直接跟随命令。
- 通常用于程序运行需要的必要的核心数据。
- 没有默认值,用户必须在命令行中提供每个位置参数的值。
例如:
parser.add_argument('file', help='The file to process')
3.2 action
在使用argparse
模块创建命令行接口时,并不是所有选项都必须传递值,这取决于你如何配置每个选项的action
。argparse
提供了多种action
类型,允许某些选项在命令行中使用时不需要显式传递值。例如:
-
store_true
和store_false
这两个动作用于布尔开关。
store_true
会在选项存在时设置属性为True
,而store_false
则相反,会在选项存在时设置属性为False
。parser.add_argument('--verbose', action='store_true', help='Verbose mode') parser.add_argument('--quiet', action='store_false', help='Quiet mode')
如果命令行是这样:
python script.py --verbose
,那么args.verbose
的值将是True
。如果没有使用--verbose
,则默认为False
。 -
store
这是默认的动作。当使用这个动作时,命令行中参数的值将被存储。如果不指定
action
,则默认为此动作。parser.add_argument('--name', action='store', help='Your name')
如果命令行是这样:
python script.py --name John
,那么args.name
的值将是字符串"John"
。 -
store_const
这个动作用于存储在命令行中指定的常量值,而不是参数本身的值。这在你想要基于不同的选项存储预定义值时非常有用。
parser.add_argument('--pi', action='store_const', const=3.14, help='Use the constant pi')
如果命令行是这样:
python test.py --pi
,那么args.pi
的值将是浮点数3.14
。 -
append
这个动作将命令行中的每个参数值添加到一个列表中。这对于收集多个值到同一参数非常有用。
parser.add_argument('--item', action='append', help='Add item to a list')
如果命令行是这样:
python test.py --item A --item B --item C
,那么args.item
的值将是列表['A', 'B', 'C']
。 -
count
这个动作用于计算特定选项出现的次数。这通常用于增加详细级别。
parser.add_argument('-v', '--verbose', action='count', help='Increase verbosity')
如果命令行是这样:
python script.py -vvv
或python script.py --verbose --verbose --verbose
,那么args.verbose
的值将是3
。
3.3 nargs
nargs
参数用于指定命令行参数应该消耗的命令行参数数量。它可以让你定义当个命令行参数接受多少个值,或者以待定的方式接受值。例如:
-
指定固定数量的值
你可以设置
nargs
为一个整数来指定应该接受的固定数量的值。parser.add_argument('--coordinates', nargs=2, help='Enter your coordinates')
这允许用户输入两个值作为坐标,如:
--coordinates 50 100
。这样,args.coordinates
将是一个列表['50', '100']
。 -
接受任意数量的值
通过将
nargs
设置为‘*’
,参数可以接受零个或多个值,所有值都将被收集到一个列表中。parser.add_argument('--name', nargs='*', help='Enter names')
这样,用户可以传递任意数量的名称,如:
--name Alice Bob Charlie
。如果没有提供--names
,args.names
将是一个空列表[]
。 -
接受至少一个值
设置
nargs
为‘+’
表示参数至少需要一个值,否则会报错。parser.add_argument('--files', nargs='+', help='List of files')
用户需要至少提供一个文件名,如:
--files 1.txt 2.txt
。这样,args.files
将是列表['1.txt', '2.txt']
。 -
接受一个可选值
通过将
nargs
设置为‘?’
,参数可以接受零个或一个值。如果提供了值,则使用该值;如果没有提供值,则使用default
指定的值(如果设置了default
)。parser.add_argument('--optional', nargs='?', const='default_value', default='no_value', help='An optional value')
如果用户运行命令
--optional
但没有提供值,args.optional
将是default_value
(因为指定了const
)。如果用户没有使用--optional
选项,args.optional
将是no_value
。
3.4 type
type
参数用于指定命令行参数应当被转换成的类型。当你的命令行工具接收一个参数时,argparse
默认将所有输入视为字符串。使用type
参数,你可以确保参数被正确地转换成另一种类型(如int
、float
或自定义的任何函数)。
-
基本类型转换
parser.add_argument('--port', type=int, help='Port number') parser.add_argument('--threshold', type=float, help='Threshold value')
在这个例子中,
–-port
后面跟随的值将被转换成整数。如果用户尝试输入一个非整数值,argparse
会报错并显示帮助信息。--threshold
后面跟随的值将被转换为浮点数。 -
使用自定义类型
你还可以定义一个函数来实现自定义的类型转换逻辑,然后将这个函数作为
type
参数的值。例如:整数类型
def positive_int(value): ivalue = int(value) if ivalue <= 0: raise argparse.ArgumentTypeError(f"{value} is an invalid positive int value") return ivalue parser.add_argument('--count', type=positive_int, help='Positive integer')
这个自定义函数
positive_int
首先尝试将值转换为整数,然后检查该值是否为正数。如果值不是正数,函数将抛出ArgumentTypeError
,argparse
会捕获这个异常并显示一个错误消息。
3.5 choices
choices
参数用于限制命令行参数的值必须从指定的一组值中选择。这对于那些只有几个固定有效值的参数非常有用,可以确保用户输入的值是预期内的,并且可以立即给出反馈如果输入了无效值。
例如:假设你正在编写一个命令行程序,需要用户选择运行模式,但运行模式只能是 fast
、slow
或 safe
中的一个。
import argparse
# 创建解析器
parser = argparse.ArgumentParser(description="Example script to demonstrate the use of choices.")
# 添加带有 choices 的参数
parser.add_argument('--mode', choices=['fast', 'slow', 'safe'], help='Operating mode')
# 解析命令行参数
args = parser.parse_args()
print(f"Selected mode: {args.mode}")
在这个例子中,如果用户尝试传入一个不在 ['fast', 'slow', 'safe']
列表中的值给 --mode
,argparse
将会报错,告诉用户正确的选择范围,并且程序不会继续执行。
3.6 required
required
参数用于指定一个命令行选项是否为必须提供的。默认情况下,所有位置参数都是必须的,而所有的可选参数都是非必须的,如果你想要一个可选参数成为执行命令时的必须项,你可以使用required=True
来指定。
例如,假设你正在编写一个命令行工具,该工具需要用户提供一个配置文件,但是配置文件的参数名希望使用一个可选参数(以 --
开头)来指定,你可以这样做:
import argparse
# 创建解析器
parser = argparse.ArgumentParser(description="Example script to demonstrate the use of required optional arguments.")
# 添加一个必须的可选参数
parser.add_argument('--config', required=True, help='Path to the configuration file')
# 解析命令行参数
args = parser.parse_args()
print(f"Using configuration file: {args.config}")
在这个例子中,虽然 --config
是以可选参数的形式定义的(因为它以 --
开头),但通过设置 required=True
,它成为了执行该命令时必须要提供的参数。如果用户运行程序时没有提供 --config
参数,argparse
会显示一个错误消息并阻止程序执行。
需要注意的是,required
参数只适用于可选参数。位置参数默认是必须的,因此不需要(也不允许)为位置参数设置required
参数。
3.7 metavar
metavar
参数用于指定帮助信息中显示的参数的名称。当你在命令行帮助信息中想要显示一个更易于理解的参数名或者当一个参数接受多个值时,想要指定这些值的名称,metavar
就非常有用。
-
单个值的情况
假设你有一个命令行参数用于指定端口号,但在帮助信息中你想要这个参数的名称显示得更明确:
import argparse # 创建解析器 parser = argparse.ArgumentParser(description="Example script to demonstrate the use of metavar.") # 添加参数,使用metavar改善帮助信息的显示 parser.add_argument('--port', type=int, help='Port number for the server', metavar='PORT') # 解析命令行参数 args = parser.parse_args() print(f"Server will run on port: {args.port}")
在这个例子中,
metavar='PORT'
指定了在帮助信息中显示的参数名称为PORT
而不是默认的--port
。 -
接受多个值的情况
当一个参数可以接受多个值时,
metavar
可以用来为这些值指定一个更加清晰的名称:parser.add_argument('--coordinates', nargs=2, type=int, help='Coordinates for the point', metavar=('X', 'Y'))
在这个例子中,
nargs=2
表明--coordinates
需要两个值。通过metavar=('X', 'Y')
,在帮助信息中这两个值将分别显示为X
和Y
,而不是重复显示参数名。
3.8 dest
dest
参数用于指定解析后的参数值应该被存储到哪个属性中。默认情况下,argparse
使用参数的长名称(去掉前缀的--
)作为属性名,但你可以通过dest
参数自定义这个属性名。
例如,假设你正在编写一个命令行程序,需要用户提供一个日志级别,但你希望在程序中通过一个简短且具有意义的属性名来访问这个值:
import argparse
# 创建解析器
parser = argparse.ArgumentParser(description="Example script to demonstrate the use of the dest parameter.")
# 添加参数,指定dest参数
parser.add_argument('--log-level', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], help='Set the logging level', dest='level')
# 解析命令行参数
args = parser.parse_args()
print(f"Logging level set to: {args.level}")
需要注意的是,当一个命令行参数同时存在多个长短选项时,argparse
默认使用第一个长选项(去掉前缀的 --
)作为 dest
的值。如果没有长选项,它会使用第一个短选项(去掉前缀的 -
)作为 dest
的值。这里的“第一个”是指在 add_argument
方法中按顺序出现的第一个选项。例如,假设你定义了以下参数,同时提供了短名称和长名称:
parser.add_argument('-v', '--verbose', action='store_true')
在这个例子中,由于 --verbose
是第一个长选项,argparse
将使用 verbose
作为默认的 dest
值。因此,你可以通过 args.verbose
来访问这个参数的值。
如果只有短选项:
parser.add_argument('-v', action='store_true')
这里没有长选项,所以 argparse
会使用 v
作为默认的 dest
值。相应地,这个参数的值可以通过 args.v
访问。
总结来说,argparse
根据你定义参数时给出的第一个长选项名来自动确定 dest
的值,如果没有长选项,则使用第一个短选项。这一行为确保了即使有多个选项名称,也能有一个明确的属性名来访问参数值。
3.9 default
default
参数在 argparse
模块的 add_argument
方法中用于指定命令行参数的默认值。如果在命令行中没有提供该参数,则会使用 default
指定的值。这使得你可以为可选参数设置一个初始值,即使用户没有在命令行中明确指定该参数。
例如:假设你正在编写一个脚本,需要用户提供一个日志级别,但你想要在用户没有指定日志级别时,默认使用 "INFO"
级别。
import argparse
# 创建解析器
parser = argparse.ArgumentParser(description="Example script to demonstrate the use of the default parameter.")
# 添加带有默认值的参数
parser.add_argument('--log-level', default='INFO', help='Set the logging level')
# 解析命令行参数
args = parser.parse_args()
print(f"Logging level: {args.log_level}")
在这个例子中,如果用户运行脚本时没有使用 --log-level
参数,args.log_level
的值将是 "INFO"
。如果用户提供了该参数,比如 --log-level DEBUG
,则 args.log_level
的值将是用户指定的 "DEBUG"
。
例如:布尔开关的默认值
布尔开关通常与 action='store_true'
或 action='store_false'
结合使用,而不是直接使用 default
。但是,你仍然可以设置布尔参数的默认值来改变其默认行为。
parser.add_argument('--verbose', action='store_true', default=False, help='Enable verbose mode')
在这个例子中,--verbose
默认为 False
。只有当用户显式地在命令行中包含 --verbose
时,它才会变为 True
。
当default
被设置为argparse.SUPPRESS
时,表示如果命令行中没有提供该选项,则解析后的对象不会包含这个选项的属性。这意味着,除非用户明确提供了该参数,否则你将无法通过解析后的命令行参数对象访问这个属性,这样可以避免未提供的选项设置默认值。
例如:假设你正在编写一个命令行工具,有一个可选的日志级别参数。如果用户没有指定这个参数,你可能不想在解析后的参数对象中看到任何默认日志级别的痕迹。
import argparse
# 创建解析器
parser = argparse.ArgumentParser(description="Example script to demonstrate the use of default=argparse.SUPPRESS.")
# 添加带有 argparse.SUPPRESS 默认值的参数
parser.add_argument('--log-level', default=argparse.SUPPRESS, help='Set the logging level')
# 解析命令行参数
args = parser.parse_args()
# 检查是否设置了 log-level
# if 'log_level' in args:
if hasattr(args, 'log_level'):
print(f"Logging level is set to: {args.log_level}")
else:
print("Logging level is not set")
在这个例子中,只有当用户显式使用 --log-level
参数时(例如,--log-level DEBUG
),args
对象才会包含 log_level
属性。如果用户没有提供 --log-level
参数,那么尝试访问 args.log_level
将会引发一个属性错误,但由于我们使用了 hasattr
函数来检查属性,所以脚本会打印出 "Logging level is not set"
消息,而不是抛出错误。
需要注意的是,如果你在使用 add_argument
方法时没有显式指定 default
参数,那么 default
的默认值会根据参数是否为可选参数(optional arguments)或位置参数(positional arguments)以及参数的 action
类型来决定:
- 对于可选参数,如果没有指定
default
,则默认值通常是None
。但是,这个默认值会根据action
类型而改变。例如,对于store_true
和store_false
动作,default
分别是False
和True
。 - 对于位置参数(没有
-
或--
前缀的参数),由于它们是必须提供的,所以没有直接相关的默认值概念。如果命令行执行时未提供必要的位置参数,argparse
会报错而不是使用某个默认值。
特定action
类型的默认值:
action='store_true'
:没有指定default
时,默认值是False
。action='store_false'
:没有指定default
时,默认值是True
。action='append'
:没有指定default
时,如果参数未在命令行中提供,则不会创建列表,相当于None
,除非通过代码显式设置。action='count'
:没有指定default
时,默认值是None
,但是通常会设置为0
来计数某个选项出现的次数。
3.10 args对象
args
变量通常是对parse_args()
方法调用结果的引用。这个方法解析命令行参数并返回应该命名空间,其中包含命令行参数的名称和值。args
变量本质上是一个带有属性的对象,它是一个Namespace
类的实例,这个类定义在argparse
模块中。