argparse模块(Python官方文档:argparse — 命令行选项、参数和子命令解析器 — Python 3.10.3 文档),可以用来在用命令行运行Python脚本时直接传参。
本文将首先给出直接可以套用的代码格式,然后在此基础上进行更多内容的介绍。
本文目前仅对argparse包的必要功能进行简要介绍,对其更深层次的应用可能会在后期继续更新。
argparse是Python自带的模块。
通过 import argparse 导入包。
一个简单的应用实例:使用argparse传入参数section_id和gpu_id,并获取两个参数(其中gpu_id直接转为torch.device1)
parser = argparse.ArgumentParser() #创建解析器 #ArgumentParser 对象包含将命令行解析成 Python 数据类型所需的全部信息。 parser.add_argument("--section_id",default='1',type=str) parser.add_argument("--gpu_id",default='0',type=str) #添加参数。后文会对各入参有详细介绍 args = parser.parse_args() #解析参数 arg_dict=args.__dict__ #将arg_dict转换为dict格式 section_id=arg_dict['section_id'] device = torch.device("cuda:"+arg_dict['gpu_id'] if torch.cuda.is_available() else "cpu")
在命令行运行如下语句即可:python example.py --section_id 2 --gpu_id 1(example.py为Python脚本,参数后面即为所需传入的值)
注意,如果使用anaconda作为环境管理器,如果想直接使用python命令,需要使terminal处在虚拟环境下;否则就要用Python解释器的路径代替python命令。
以下示例及整体内容架构参考自官方文档:
示例prog.py(获取一个列表,并计算其总和或最大值):
import argparse parser = argparse.ArgumentParser(description='Process some integers.') #description是在参数帮助文档之前显示的文本 parser.add_argument('integers', metavar='N', type=int, nargs='+', help='an integer for the accumulator') parser.add_argument('--sum', dest='accumulate', action='store_const', const=sum, default=max, help='sum the integers (default: find the max)') #integers 属性将是一个包含一个或多个整数的列表 #accumulate 属性当命令行中指定了 --sum 参数时将是 sum() 函数,否则则是 max() 函数。 args = parser.parse_args() print(args.accumulate(args.integers))
在命令行运行 python prog.py -h,得到提示信息:
usage: prog.py [-h] [--sum] N [N ...] Process some integers. positional arguments: N an integer for the accumulator options: -h, --help show this help message and exit --sum sum the integers (default: find the max)
计算最大值的示例:python prog.py 1 2 3 4
求和的示例:python prog.py 1 2 3 4 --sum
传入无效参数并报错的示例:python prog.py a b c
报错信息:
usage: prog.py [-h] [--sum] N [N ...] prog.py: error: argument N: invalid int value: 'a'
add_argument() 方法(以下只列举一部分入参):
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
- name or flags - 一个命名或者一个选项字符串的列表,例如 foo 或 -f, --foo。
前面带-或--的就是optional argument,否则就是positional argument(在命令行中必须传入)。第一个传入的参数可以是一系列flags,也可以是单个argument name。
创建optional argument举例:parser.add_argument('-f', '--foo')(这是一种缩写形式,可以直接用-f或--foo传入参数)
创建positional argument举例:parser.add_argument('bar')
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-f', '--foo') >>> parser.add_argument('bar') >>> parser.parse_args(['BAR']) Namespace(bar='BAR', foo=None) >>> parser.parse_args(['BAR', '--foo', 'FOO']) Namespace(bar='BAR', foo='FOO') >>> parser.parse_args(['--foo', 'FOO']) usage: PROG [-h] [-f FOO] bar PROG: error: the following arguments are required: bar
- action - 当参数在命令行中出现时使用的动作基本类型。
- 默认值 ‘store’:存储参数值
- ‘store_const’:存储const keyword argument指定的值。
- ‘store_true’:用参数传递布尔值。示例用法:
import argparse parser = argparse.ArgumentParser() parser.add_argument("-a",action="store_true") args = parser.parse_args() print(type(args.a)) print(args.a)
不传入参数的输出:
<class 'bool'> False
-a的输出:
<class 'bool'> True
- nargs - 单个action关联几个参数。
- ‘*’:整合所有参数为一个list
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs='*') >>> parser.add_argument('--bar', nargs='*') >>> parser.add_argument('baz', nargs='*') >>> parser.parse_args('a b --foo x y --bar 1 2'.split()) Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
- ‘+’:与 ‘*’ 类似,但是如果没有传入至少一个参数就会报error。
>>> parser = argparse.ArgumentParser(prog='PROG') #prog入参是程序名称,默认值为os.path.basename(sys.argv[0]) >>> parser.add_argument('foo', nargs='+') >>> parser.parse_args(['a', 'b']) Namespace(foo=['a', 'b']) >>> parser.parse_args([]) usage: PROG [-h] foo [foo ...] PROG: error: the following arguments are required: foo
- const - 被一些 action 和 nargs 选择所需求的常数。如果入参action='store_const’或’append_const’会将该值与某一参数值加起来,且该值必须被赋值。默认值为None
- default - 默认值,当参数未在命令行中出现并且也不存在于命名空间对象时所使用的值。
optional argument在option name在命令行中未出现时使用:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', default=42) >>> parser.parse_args(['--foo', '2']) Namespace(foo='2') >>> parser.parse_args([]) Namespace(foo=42)
如果目标namespace已经有attribute set了,就不会用:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', default=42) >>> parser.parse_args([], namespace=argparse.Namespace(foo=101)) Namespace(foo=101)
如果default值是字符串,parser就会跟命令行一样传参,比如自动根据type值进行转换;否则就使用原object:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--length', default='10', type=int) >>> parser.add_argument('--width', default=10.5, type=int) >>> parser.parse_args() Namespace(length=10, width=10.5)
- type - 命令行参数应当被转换成的类型。
可以是任何一个callable、入参为单一str的函数,如float、int、ascii、ord、open、argparse.FileType('w', encoding='latin-1')、pathlib.Path,也可以是用户自定义的函数。
只能返回ArgumentTypeError、TypeError或ValueError。
不建议使用bool,因为它仅会置空字符串为False,非空字符串为True。
(需要注意的是,如果直接不输入参数或者以空格作为参数,会报错error: argument --argument_name: expected one argument;如果输入""或''为参数,才会转换为False。直接写None也不会(因为直接识别的是字符串'None'))
只建议做简单处理。有些问题是报错信息太复杂。FileType的问题是不会自动close文件。
- help - 一个对此参数作用的简单描述。
在命令行中通过-h或-help参数查看。
- metavar - 在usage messages中显示的参数名。
在ArgumentParser生成的help信息中需要区别各项参数,默认用dest值作为object名。positional argument actions直接用dest值,optional argument actions大写dest值,metavar则是可选名。metavar仅改变展示时的名字,属性名仍然是dest值。不同取值的nargs可能使metavar多次被使用。
简单示例:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', metavar='YYY') >>> parser.add_argument('bar', metavar='XXX') >>> parser.parse_args('X --foo Y'.split()) Namespace(bar='X', foo='Y') >>> parser.print_help() usage: [-h] [--foo YYY] XXX positional arguments: XXX options: -h, --help show this help message and exit --foo YYY
用元组传入多个metavar的实例:
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-x', nargs=2) >>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz')) >>> parser.print_help() usage: PROG [-h] [-x X X] [--foo bar baz] options: -h, --help show this help message and exit -x X X --foo bar baz
- dest - parse_args() 返回对象的属性名。
默认值:
positional argument actions就是add_argument()的第一个入参。
示例:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('bar') >>> parser.parse_args(['XXX']) Namespace(bar='XXX')
optional argument actions是从option strings中推理得出的:从第一个开始挑一个可以开头有--的option string然后去掉--,如果没有就换成-。然后将option string中间的-全部改成_
示例:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('-f', '--foo-bar', '--foo') >>> parser.add_argument('-x', '-y') >>> parser.parse_args('-f 1 -x 2'.split()) Namespace(foo_bar='1', x='2') >>> parser.parse_args('--foo 1 -y 2'.split()) Namespace(foo_bar='1', x='2')
指定dest入参值:
示例:
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', dest='bar') >>> parser.parse_args('--foo XXX'.split()) Namespace(bar='XXX')