- argparse模块可以让你轻松编写用户友好的命令行接口。
- 程序定义它需要的参数,然后argparse知道如何从sys.argv解析出那些参数,并在用户给程序传入无效参数时报出错误信息。
- argparse模块还会自动生成帮助和使用手册。
1、创建解析器
- ArgumentParser对象包含将命令行解析成Python数据类型所需的全部信息。
- 给ArgumentParser添加程序参数是通过调用add_argument()方法完成的。通常,add_argument()方法将指定ArgumentParser如何获取命令行字符串并将其转换为python对象。
-
ArgumentParser通过parse_args()方法解析参数。它将检查命令行,把每个参数转换为适当的类型然后调用相应的操作。
参数信息在调用parse_args()时被存储和使用。
import argparse parser = argparse.ArgumentParser(description='Process some integers.') #创建解析器 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)') args = parser.parse_args() #解析参数 print(args) print(args.integers) print(args.accumulate(args.integers)) >>> #cmd运行中 PS C:\Users\root> python3 D:\test\python\test\hh.py 1 2 3 4 --sum <<< #结果输出 Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4]) [1, 2, 3, 4] 10
2、ArgumentParser对象
class argparse.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:描述程序的使用方法(默认值:从添加到解析器的参数生成)
- description:在参数帮助文档之前显示的文本(默认值:无)
- epilog:在参数帮助文档之后显示的文本(默认值:无)
- parents:一个 ArgumentParser 对象的列表,它们的参数也应包含在内
- formatter_class:用于自定义帮助文档输出格式的类
- prefix_chars:可选参数的前缀字符集合(默认值: '-')
- fromfile_prefix_chars:当需要从文件中读取其他参数时,用于标识文件名的前缀字符集合(默认值: None)
- argument_default:参数的全局默认值(默认值: None)
- conflict_handler:解决冲突选项的策略(通常是不必要的)
- add_help:为解析器添加一个 -h/--help 选项(默认值: True)
- allow_abbrev:如果缩写是无歧义的,则允许缩写长选项 (默认值:True)
1、prog:程序名称
- 默认情况下,程序名称使用sys.argv[0]的值。
- 程序名称可以在帮助信息中通过%(prog)s格式说明符来引用。
import argparse parser = argparse.ArgumentParser() # parser = argparse.ArgumentParser(prog='myprogram') parser.add_argument('--foo', help='foo of the %(prog)s program') args = parser.parse_args() >>> PS D:\test\python> python3 D:\test\python\test\hh.py -h <<< usage: hh.py [-h] [--foo FOO] #注意,程序名称 optional arguments: -h, --help show this help message and exit --foo FOO foo of the hh.py program #注意,程序名称引用
2、usage:脚本的用法说明
- 自定义程序的使用方法。
import argparse parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]') parser.add_argument('--foo', nargs='?', help='foo help') parser.add_argument('bar', nargs='+', help='bar help') parser.print_help() <<< PS D:\test\python> python3 D:\test\python\test\hh.py -h >>> usage: PROG [options] #注意,自定义程序使用说明 positional arguments: bar bar help optional arguments: -h, --help show this help message and exit --foo [FOO] foo help
3、description:文档前的说明信息
- 在帮助文档之前,简要描述这个程序做什么以及怎么做。
- 在帮助消息中,这个描述会显示在命令行用法字符串和各种参数的帮助消息之间。
- 默认会换行,可以使用formatter_class参数改变。
import argparse parser = argparse.ArgumentParser(description='A foo that bars') parser.print_help() >>> PS D:\test\python> python3 D:\test\python\test\hh.py -h <<< usage: hh.py [-h] A foo that bars #注意,description optional arguments: -h, --help show this help message and exit
4、epilog:文档后的说明信息
- 在帮助文档之后显示。
- 默认会换行,可以使用formatter_class参数改变。
import argparse parser = argparse.ArgumentParser(description='A foo that bars', epilog="And that's how you'd foo a bar") parser.print_help() >>> PS D:\test\python> python3 D:\test\python\test\hh.py -h <<< usage: hh.py [-h] A foo that bars #注意,description optional arguments: -h, --help show this help message and exit And that's how you'd foo a bar #注意,epilog
5、parents:父子解析器
- 在通过parents=传递解析器之前,必须完全初始化它们。
- 如果在子解析器之后更改父解析器,这些更改将不会反映在子解析器中。
import argparse parent_parser = argparse.ArgumentParser(add_help=False) #定义父解析器 parent_parser.add_argument('--parent', type=int) foo_parser = argparse.ArgumentParser(parents=[parent_parser]) #定义子解析器,注意parents的值是父解析器对象[parent_parser] foo_parser.add_argument('foo') print(foo_parser.parse_args()) print(foo_parser.parse_args(['XXX'])) bar_parser = argparse.ArgumentParser(parents=[parent_parser]) #定义子解析器,注意parents的值是父解析器对象[parent_parser] bar_parser.add_argument('--bar') print(bar_parser.parse_args(['--bar', 'YYY'])) >>> PS D:\test\python> python3 D:\test\python\test\hh.py 'fff' --parent 2 <<< Namespace(foo='fff', parent=2) Namespace(foo='XXX', parent=None) Namespace(bar='YYY', parent=None)
6、formatter_class:控制帮助信息的格式
- formatter_class定义description和epilog的格式,它的值是四个类:
- class argparse.RawDescriptionHelpFormatter
- 表示description和epilog已经被正确的格式化了,不能在命令行中被自动换行
- 多个连续空格:description和epilog中的全部被保留,参数描述中的只保留一个。多个连续空行只保留一个,如果想保留多重的空白行,可以在空行中加空格。
- class argparse.RawTextHelpFormatter
- 表示description和epilog已经被正确的格式化了,不能在命令行中被自动换行
- 多个连续空格:全部被保留(description、epilog和参数描述中的空格)。多个连续空行只保留一个,如果想保留多重的空白行,可以在空行中加空格。
- class argparse.ArgumentDefaultsHelpFormatter
- 参数的帮助信息中会添加默认值
- class argparse.MetavarTypeHelpFormatter
- 参数的帮助信息中会使用type的值当作它的显示名
- 每一个参数都要有type,否则异常
- 不设置formatter_class
- 默认情况下,ArgumentParser对象会将description和epilog的文字在命令行中自动换行。
- class argparse.RawDescriptionHelpFormatter
import argparse parser = argparse.ArgumentParser( prog='PROG', # formatter_class=argparse.RawDescriptionHelpFormatter, # formatter_class=argparse.RawTextHelpFormatter, # formatter_class=argparse.ArgumentDefaultsHelpFormatter, # formatter_class=argparse.MetavarTypeHelpFormatter, description=''' this description was indented weird but that is okay''', epilog=''' likewise for this epilog whose whitespace will be cleaned up and whose words will be wrapped across a couple lines''') parser.add_argument('--foo', type=int, default=42, help='FO O!') parser.add_argument('bar', type=float, nargs='*', default=[1, 2, 3], help='BA R!') #type=float是后加的,否则formatter_class=argparse.RawTextHelpFormatter时会异常 parser.print_help() >>> PS C:\Users\root> python3 D:\test\python\test\hh.py <<< #默认,不设置formatter_class参数 usage: PROG [-h] [--foo FOO] [bar [bar ...]] this description was indented weird but that is okay positional arguments: bar BA R! optional arguments: -h, --help show this help message and exit --foo FOO FO O! likewise for this epilog whose whitespace will be cleaned up and whose words will be wrapped across a couple lines <<< #formatter_class=argparse.RawDescriptionHelpFormatter usage: PROG [-h] [--foo FOO] [bar [bar ...]] this description was indented weird but that is okay positional arguments: bar BA R! optional arguments: -h, --help show this help message and exit --foo FOO FO O! likewise for this epilog whose whitespace will be cleaned up and whose words will be wrapped across a couple lines <<< #formatter_class=argparse.RawTextHelpFormatter usage: PROG [-h] [--foo FOO] [bar [bar ...]] this description was indented weird but that is okay positional arguments: bar BA R! optional arguments: -h, --help show this help message and exit --foo FOO FO O! likewise for this epilog whose whitespace will be cleaned up and whose words will be wrapped across a couple lines <<< #formatter_class=argparse.ArgumentDefaultsHelpFormatter usage: PROG [-h] [--foo FOO] [bar [bar ...]] this description was indented weird but that is okay positional arguments: bar BA R! (default: [1, 2, 3]) optional arguments: -h, --help show this help message and exit --foo FOO FO O! (default: 42) likewise for this epilog whose whitespace will be cleaned up and whose words will be wrapped across a couple lines <<< #formatter_class=argparse.MetavarTypeHelpFormatter usage: PROG [-h] [--foo int] [float [float ...]] this description was indented weird but that is okay positional arguments: float BA R! optional arguments: -h, --help show this help message and exit --foo int FO O! likewise for this epilog whose whitespace will be cleaned up and whose words will be wrapped across a couple lines
7、prefix_chars:命令行参数的前缀
- 命令行参数默认使用 '-'当作前缀。
- 如果解析器需要支持不同的或者额外的字符,比如像+f或者/foo的选项,可以在参数解析构建器中使用prefix_chars。
import argparse parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+') parser.add_argument('+f') parser.add_argument('++bar') print(parser.parse_args()) >>> PS C:\Users\root> python3 D:\test\python\test\hh.py +f hh ++bar bbb <<< Namespace(bar='bbb', f='hh')
8、fromfile_prefix_chars:参数与文件
- 当处理一个特别长的命令行参数列表的时候,将其放在文件中会更方便。(将命令行参数放在文件中)
- 从文件读取的参数在默认情况下必须一个一行,并且与命令行上的原始文件引用参数位于同一位置。
- 重复的参数,位于后面的生效
- 默认fromfile_prefix_chars = None,意味着参数不会被当作文件对待。
import argparse with open('args.txt', 'w') as fp: fp.write('-a\naaa\n-f\nfff') parser = argparse.ArgumentParser(fromfile_prefix_chars='@') parser.add_argument('-a') parser.add_argument('-f') parser.add_argument('--bar') print(parser.parse_args(['-f', 'FFF', '@args.txt', '-a', 'AAA', '--bar', 'BBB'])) <<< Namespace(a='AAA', bar='BBB', f='fff')
- 例如,['-f', 'FFF', '@args.txt', '-a', 'AAA', '--bar', 'BBB']等价于['-f', 'FFF', '-a', 'aaa', '-f', 'fff', '-a', 'AAA', '--bar', 'BBB']
9、argument_default
import argparse parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS) parser.add_argument('--foo',default=[1, 2, 3]) parser.add_argument('bar', nargs='?') print(parser.parse_args(['--foo', '1', 'BAR'])) print(parser.parse_args([]) <<< Namespace(bar='BAR', foo='1') Namespace(foo=[1, 2, 3]) #默认的输出是:Namespace(bar=None, foo=[1, 2, 3])
10、allow_abbrev:长选项的缩写
- 默认情况下,可以使用长选项的缩写。
- allow_abbrev=False,禁止长选项使用缩写。
import argparse parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False) parser.add_argument('--foobar', action='store_true') parser.add_argument('--foonley', action='store_false') print(parser.parse_args(['--foon'])) <<< usage: PROG [-h] [--foobar] [--foonley] PROG: error: unrecognized arguments: --foon
11、conflict_handler:重写命令行参数
- 默认情况下,在相同选项下不允许有两种行为。
- conflict_handler='resolve',重写旧的相同选项
import argparse parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve') parser.add_argument('-f', '--foo', help='old foo help') #有两个--foo选项 parser.add_argument('-d', '--foo', help='new foo help') print(parser.parse_args(['-d', 'fff'])) #注意,这里用的短选项-d <<< Namespace(foo='fff')
12、add_help:-h/--help
- 默认情况下,帮助信息会有"-h, --help show this help message and exit"
- add_help=False,可以禁止在命令行中使用-h/--help,并禁止帮助信息中显示"-h, --help show this help message and exit"
示例1:默认
import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo', help='foo help') args = parser.parse_args() >>> PS C:\Users\root> python3 D:\test\python\test\hh.py -h <<< usage: hh.py [-h] [--foo FOO] optional arguments: -h, --help show this help message and exit --foo FOO foo help
示例2:add_help=False
import argparse parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--foo', help='foo help') parser.print_help() args = parser.parse_args() >>> PS C:\Users\root> python3 D:\test\python\test\hh.py --help <<< usage: hh.py [--foo FOO] optional arguments: --foo FOO foo help usage: hh.py [--foo FOO] hh.py: error: unrecognized arguments: --help
3、add_argument()方法
- 定义单个的命令行参数应当如何解析。
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
- name or flags:选项名称或选项字符串的列表,例如 foo 或 -f, --foo。
- action:当参数在命令行中出现时使用的动作。
- nargs:命令行参数应当消耗的数目。
- const:被一些 action 和 nargs 选择所需求的常数。
- default:当参数未在命令行中出现时使用的值。
- type:命令行参数应当被转换成的数据类型。
- choices:可用的参数的容器。
- required:此命令行参数是否可省略 (仅选项可用)。
- help:此参数作用的简单描述。
- metavar:在使用方法消息中使用的参数值示例。
- dest:被添加到 parse_args() 所返回对象上的属性名。
1、name or flags:参数名称
- 可选参数:带参数前缀的是可选参数,例如 -f 或 --foo,(长短参数。没有默认值时,可缺省,其值是None)
- 位置参数:不带参数前缀的是位置参数,例如 bar(必须参数。没有默认值时,不可缺省)
- 当parse_args()被调用,长短参数会以 - 前缀识别,剩下的参数则会被假定为位置参数
import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo') parser.add_argument('--zoo') parser.add_argument('bar') parser.add_argument('par') print(parser.parse_args()) >>> PS C:\Users\root> python3 D:\test\python\test\hh.py --foo fff bbb ppp <<< Namespace(bar='bbb', foo='fff', par='ppp', zoo=None)
2、action:参数的动作
- action指定了这个命令行参数出现时应当如何处理。
- action的值可以是:
- 'store':存储参数的值。这是默认的动作
- 'store_const':存储被const指定的值。
- 'store_true':等价于'store_const'存储True,且默认值分别为False
- 'store_false':等价于'store_const'存储False,且默认值分别为True。
- 'append':存储一个列表,并且将每个参数值追加到列表中。允许同一个参数多次使用。
- 'append_const':这存储一个列表,并将const指定的值追加到列表中(注意const的值默认是None。)。一般在多个参数需要在同一列表中存储常数时会有用。
- 'extend':这会存储一个列表,并将每个参数值加入到列表中。
- 'count':计算一个关键字参数出现的数目或次数
- 'help':打印所有当前解析器中的选项和参数的完整帮助信息,然后退出。默认情况下,一个 help 动作会被自动加入解析器
- 'version':期望有一个 version= 命名参数在 add_argument() 调用中,并打印版本信息并在调用后退出
- 自定义
1、store
- 默认动作,存储参数的值。
import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo') print(parser.parse_args('--foo 1'.split())) <<< Namespace(foo='1')
2、store_const
- 存储被const指定的值。
- 该命令行参数出现时其值被固定,即不能再为其赋值,否则异常。
- 用于可选参数。
import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo', action='store_const', const=42) print(parser.parse_args(['--foo'])) <<< Namespace(foo=42)
3、store_true和store_false
- 'store_true':等价于'store_const'存储True,且默认值分别为False
- 'store_false':等价于'store_const'存储False,且默认值分别为True。
- 用于可选参数。
import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo', action='store_true') parser.add_argument('--bar', action='store_false') parser.add_argument('--baz', action='store_false') print(parser.parse_args('--foo --bar'.split())) <<< Namespace(bar=False, baz=True, foo=True)
4、append
- 存储一个列表,并且将每个参数值追加到列表中。
- 允许同一个参数多次使用。
- 用于可选参数
import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo', action='append') print(parser.parse_args('--foo 1 --foo 2 '.split())) <<< Namespace(foo=['1', '2'])
5、append_const
- 存储一个列表,并将const指定的值添加到列表中。(注意const关键字参数默认为None。)
- 当多个参数需要将常量存储到同一个列表中时,append_const通常很有用。必须与dest一起使用
- 用于可选参数。
import argparse parser = argparse.ArgumentParser() parser.add_argument('--str', dest='types', action='append_const', const=str) parser.add_argument('--int', dest='types', action='append_const', const=int) print(parser.parse_args('--str --int'.split())) <<< Namespace(types=[<class 'str'>, <class 'int'>])
6、extend
- 存储一个列表,并将每个参数值加入到列表中。
- 用于可选参数
import argparse parser = argparse.ArgumentParser() parser.add_argument("--foo", action="extend", nargs="+", type=str) print(parser.parse_args(["--foo", "f1", "--foo", "f2", "f3", "f4"])) <<< Namespace(foo=['f1', 'f2', 'f3', 'f4'])
7、count
- 计算一个关键字参数出现的数目或次数。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--verbose', '-v', action='count', default=0) #default将为None
,除非显式地设为0
print(parser.parse_args(['-vvv']))
<<<
Namespace(verbose=3)
8、help
- 给参数添加帮助信息
- 默认情况下,一个 help 动作会被自动加入解析器
import argparse parser = argparse.ArgumentParser() parser.add_argument('--verbose', '-v', action='count', default=0, help='v出现的次数') parser.parse_args() >>> PS C:\Users\root> python3 D:\test\python\test\hh.py -h <<< usage: hh.py [-h] [--verbose] optional arguments: -h, --help show this help message and exit --verbose, -v v出现的次数
9、version
- 在add_argument()调用中需要一个version=关键字参数,打印版本信息并在调用时退出
import argparse parser = argparse.ArgumentParser(prog='PROG') parser.add_argument('--version', action='version', version='%(prog)s 2.0') parser.parse_args(['--version']) <<< PROG 2.0
3、nargs:设定参数的参数值数量
- ArgumentParser对象通常将一个命令行参数值关联到到一个命令行参数。
- nargs可以将不同数目的命令行参数值关联到到一个命令行参数。
- nargs的值有:
- N:一个整数,一个参数关联多个参数值
- '?':一个参数关联一个参数值
- '*':一个参数关联多个参数值
- '+':一个参数关联多个参数值
- argarse.REMAINDER:将剩余所有的命令行参数值聚集到一个列表中
1、N:一个整数,一个参数关联多个参数值
- 命令行中的N个参数被聚集到一个列表中。
- 注意nargs=1会产生一个单元素列表。这和默认的元素本身是不同的。
import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo', nargs=1) parser.add_argument('bar', nargs=2) print(parser.parse_args('c v --foo b'.split())) <<< Namespace(bar=['c', 'v'], foo=['b'])
2、?:一个参数关联一个参数值
- 将一个命令行参数值关联到到一个命令行参数。
- 可选参数:
- 有参数和参数值,参数的值是参数值;
- 仅有参数,没有参数值,参数的值是const的值;
- 既无参数,也无参数值,参数的值是default的值
- 位置参数:没有值,使用default的值
- 可选参数:
import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo', nargs='?', const='c', default='d') parser.add_argument('bar', nargs='?', default='d') print(parser.parse_args(['XX', '--foo', 'YY'])) print(parser.parse_args(['XX', '--foo'])) print(parser.parse_args([])) <<< Namespace(bar='XX', foo='YY') Namespace(bar='XX', foo='c') Namespace(bar='d', foo='d')
- 通常用法是允许可选的输入或输出文件
import argparse import sys parser = argparse.ArgumentParser() parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin) parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout) print(parser.parse_args(['args.txt', 'args.txtt'])) print(parser.parse_args([])) <<< Namespace(infile=<_io.TextIOWrapper name='args.txt' mode='r' encoding='cp936'>, outfile=<_io.TextIOWrapper name='args.txtt' mode='w' encoding='cp936'>) Namespace(infile=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>, outfile=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)
3、*:一个参数关联多个参数值
- 当前命令行参数值被聚集到一个列表中。
- 注意:多个位置参数通常没有意义,但是多个选项是可能的。
import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo', nargs='*') parser.add_argument('--bar', nargs='*') parser.add_argument('baz', nargs='*') print(parser.parse_args('a b --foo x y --bar 1 2'.split())) <<< Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
4、'+':一个参数关联多个参数值
- 当前命令行参数值被聚集到一个列表中。
- 和 '*' 类似,但至少要有一个参数值,否则异常。
import argparse parser = argparse.ArgumentParser(prog='PROG') parser.add_argument('foo', nargs='+') print(parser.parse_args(['a', 'b'])) print(parser.parse_args([])) <<< Namespace(foo=['a', 'b']) usage: PROG [-h] foo [foo ...] PROG: error: the following arguments are required: foo
5、argarse.REMAINDER:将剩余所有的命令行参数值聚集到一个列表中
- 通常在从一个命令行传递参数到另一个命令行中时有用。
import argparse parser = argparse.ArgumentParser(prog='PROG') parser.add_argument('--foo') parser.add_argument('command') parser.add_argument('args', nargs=argparse.REMAINDER) print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split())) <<< Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
4、const
- action='store_const'或action='append_const时,const必须给出。
- 可选参数并且nargs='?'时,可能需要const。