当前位置: 首页 > 后端技术 > Python

Pythonargparse标准库快速入门

时间:2023-03-25 23:06:54 Python

Python是一种非常容易上手的脚本语言,用它来开发命令行程序自然会更加方便。而且在Python的标准库中有一个叫做argparse的库,非常方便我们将命令行参数转换成需要的数据格式。下面我们就来看看如何使用argparse标准库。如果你想了解更多关于argparse的知识,你可以查看Python官方文档。中文版的文档已经发布,极大的方便了我们中国的开发者。虽然有些地方没有完整的翻译,但是完全够用了。初见argparse,我们先来看看argparse的基本用法。下面是最简单的例子。可以看到argparse标准库其实使用起来非常简单,分为三步:创建ArgumentParser对象,使用add_argument方法添加参数,使用parse_args方法接受并解析对象。让我们依次看看这些步骤。importargparseparser=argparse.ArgumentParser()parser.add_argument('-from',type=str)parser.add_argument('-to',type=str,default='everyone')args=parser.parse_args('-fromyitian'.split(''))print(args)#运行结果#Namespace(from='yitian',to='everyone')ArgumentParserArgumentParser是最重要的一个类,如果要使用argparse标准就必须创建这个类的库实例。如有必要,可以通过在构造函数中设置各种参数来修改ArgumentParser类的行为。由于参数项较多,官方文档建议我们使用关键字parameters来添加参数。prog-程序的名称(默认:sys.argv[0]),默认是Python程序的文件名usage-描述程序用法的字符串(默认:从添加到解析器的参数生成)description-in参数帮助文档之前显示的文本(默认值:无)epilog-在参数帮助文档之后显示的文本(默认值:无)parents-ArgumentParser对象的列表,其参数也应包括在内。如果多个解析器有一些可以共享的参数,可以通过设置子解析器来共享formatter_class-用于自定义帮助文档输出格式的类prefix_chars-可选参数的前缀字符集(默认值:'-')fromfile_prefix_chars-当其他参数需要从文件中读取时,用于标识文件名的前缀字符集(默认值:None)argument_default-参数的全局默认值(默认值:None),如果需要指定所有参数默认的通用一个,可以修改,如果要全局禁用默认,可以使用argparse.SUPRESSconflict_handler-解决冲突选项的策略(通常是不必要的)add_help-添加-h/--help选项解析器(默认值:True)allow_abbrev-如果缩写是明确的(默认值:True)允许缩写的长选项程序可以接受的参数。这个参数比较复杂,功能也很强大。名称或标志-名称或选项字符串列表,例如foo或-f,--foo。action-当参数出现在命令行上时要使用的基本操作类型。nargs-应该使用的命令行参数的数量。const-某些操作和nargs选项所需的常量。default-当参数没有出现在命令行中时使用的值。type-命令行参数应转换成的类型。choices-可用参数的容器。required-此命令行选项是否可以省略(只有选项可用)。help-简要说明此选项的作用。metavar-在方法消息中使用的参数值示例。dest-要添加到parse_args()返回的对象的属性的名称。参数名方法的第一个参数是参数名,可以是一个字符串(名称)或一组以-开头的字符串(标志)。前者是位置参数,会按照相加的顺序读取;后者是关键字参数,可以按任何顺序指定。如果指定关键字参数(标志),则可以同时添加缩写和全名,需要分别以-和--作为前缀。导入argparseparser=argparse.ArgumentParser()parser.add_argument('foo')parser.add_argument('bar')parser.add_argument('-f','--ff',action='store_true')args=parser.parse_args('FOOBAR-f'.split(''))print(args)args=parser.parse_args('--ffBARFOO'.split(''))print(args)'''运行结果,注意指定参数的不同参数和得到的结果Namespace(bar='BAR',ff=True,foo='FOO')Namespace(bar='FOO',ff=True,foo='BAR')'''action(行为)接下来介绍的参数是关键字参数,可以根据需要指定。这里比较重要的是action,它指定读取参数后下一步要做什么。这部分可以看官方文档,比较全面,有相应的例子。我在这里简单介绍一下。store和store_const用于保存特定的值。它们之间有一些区别,后面会介绍。store_true和store_false比较方便,可以用来设置一些开关参数。比如我想在指定-f时启用某个功能,忽略这个参数时不执行,那么我可以指定它的行为为store_true,然后在程序中就可以得到名为f的参数的真值,然后做一个简单的条件判断就可以了。append和append_const会将参数存储为列表。count将存储参数出现的次数。一个常见的用法是指定日志输出级别。比如有些程序-v会显示简单的输出,-vv会显示复杂的输出。即使需求再复杂一些,也可以自己实现一个新的Action类,然后添加到add_argument方法中。nargs(参数个数)这个参数指定了你的程序可以接受的参数个数。您可以使用以下值:N(正整数),这意味着接下来的N个值将被读取为参数。请注意,如果指定1将成为单元素列表。?,类似于正则表达式中的概念,会读取下一个值,如果没有,则从默认值开始读取。+,会读取后面的多个值,如果没有则抛出异常。?,下面会读取多个值,没有值也没关系。argparse.REMAINDER,它会读取后面所有的值作为参数,通常用来给其他命令行传递参数。默认情况下,nargs会根据动作的类型判断参数个数,store和store_const会读取后面的值作为参数。const参数需要与带有const的动作结合使用。default指定参数的默认值。这是一个非常有趣的观点。如果仔细阅读官方文档,你可能会有和我一样的疑问:store_const和const可以一起使用来指定一个默认值,store和default也可以指定一个默认值。有什么不同?其实区别挺大的,看看下面的例子就明白了。importargparseparser=argparse.ArgumentParser()parser.add_argument('-foo',action='store',nargs='?',default=10,const=20)print(parser.parse_args('-foo0'.split('')))print(parser.parse_args('-foo'.split('')))print(parser.parse_args(''))'''命名空间(foo='0')命名空间(foo=20)Namespace(foo=10)'''当完全忽略foo参数时,将使用默认值。当指定了foo参数但没有指定后续值时,将使用const值。当指定foo参数和后续值时,将使用我们指定的值。type这个是指定参数类型,int,float,str那些。当然,比较特殊的是open,将参数作为文件打开。如果默认打开还不够,还可以使用argparse.FileType,它提供了读写模式、文件编码、缓冲区大小等详细设置。parser.add_argument('bar',type=argparse.FileType('w'))即使有需要,我们也可以在这里使用我们自己的函数,只要它的参数是一个字符串,返回值是转换后的价值可以。choices如果确认参数范围限定为几个固定值,可以使用choices参数指定。可接受的值包括字面值列表和范围函数。required指定参数是否是必需的。metavar和dest参数用于指定参数的显示名称,dest用于指定底层参数使用的属性名。注意下面的程序输出,foo参数只是修改了metavar,所以在帮助信息输出中发生了变化,但是foo还是用来保存Namespace最底层的值。bar参数修改了dest,所以底层属性名变了,但是帮助信息没有变。importargparseparser=argparse.ArgumentParser()parser.add_argument('-foo',metavar='foooo')parser.add_argument('-bar',dest='barrrr')parser.print_help()print(parser.parse_args(''))'''用法:argparse_sample.py[-h][-foofoooo][-barbar]可选参数:-h,--help显示此帮助信息并退出-foofoooo-barbarNamespace(barrrr=None,foo=None)'''help如果条件允许,最好在每个参数中加入帮助信息,这样用户在使用-h命令时就可以看到该参数的帮助信息。parse_args方法参数编辑完成后,可以调用parse_args方法对参数进行处理,它会返回一个命名空间对象,其中包含解析后的参数。如果你想测试这个方法,你可以手动给它传递一组参数,否则它会自动从命令行读取参数。此外,它还支持几个有用的特性:如果参数比较长,可以用等号连接参数和值,比如-foo=bar。如果参数是单个字母长度,可以直接把参数和值写在一起。导入argparseparser=argparse.ArgumentParser()parser.add_argument('-foo')parser.add_argument('-b')print(parser.parse_args('-foo=bar'.split()))print(parser.parse_args('-bX'.split()))'''Namespace(b=None,foo='bar')Namespace(b='X',foo=None)'''还支持默认的明确参数缩写。importargparseparser=argparse.ArgumentParser()parser.add_argument('-f1aaaaaaaaa')parser.add_argument('-f2aaaaaaaaa')print(parser.parse_args('-f1a-f2b'.split(''))命名空间为在对象之前可以看到,解析参数后返回的值是一个命名空间对象,使用起来非常简单,直接访问属性值即可。导入argparseparser=argparse.ArgumentParser()parser.add_argument('-a')parser.add_argument('-b')args=parser.parse_args('-aa-bb'.split(''))print(args.a)#aOtherfeaturesargparse还支持一些其他的特性,这里就不介绍了。详情请直接参考官方文档。子解析器。一些程序支持子命令,子解析器可用于创建更复杂的解析器。文件类型。更详细的文件参数设置方法。参数组。如果参数较多,可以使用参数组将功能相似的参数进行分组,这样开发者和用户都可以更清晰的使用参数。互斥参数组。如果某些参数不能同时使用,可以将它们添加到互斥参数组中。部分解析。默认情况下,parse_argument在遇到未知参数时会报错。如果需要保存这些参数并传递给其他命令行,可以使用parse_known_args方法。它不会因为未知参数而报错,并将所有未知参数存储为一个列表作为第二个返回值。简单的例子说了很久,你可能还不知道argparse怎么用,其实只需要看一个简单的例子就可以了。保存下面的文件,然后用命令行调用它,看看不同参数的输出是什么。importargparseparser=argparse.ArgumentParser(prog='ParserSample',description='简单示例程序,学习如何解析命令行参数',epilog='简单易学')parser.add_argument('greeting',type=str,help='问候语,必填')parser.add_argument('-fromm',default='yitian',type=str,help='sender,默认为yitian')parser.add_argument('-to',default='everyone',type=str,nargs='*',help='Receiver,默认为everyone')parser.add_argument('-p',action='store_true',help='是否加感叹号')args=parser.parse_args()output=f'{args.fromm}说{args.greeting}到{args.to}'ifargs.p:output=output+'!'print(output)'''usage:ParserSample[-h][-frommFROMM][-to[TO[TO...]]][-p]greeting简单示例程序,学习如何解析命令行参数positionalarguments:greeting问候信息,必需的可选参数:-h,--help显示此帮助信息并退出-frommFROMM发件人,默认为倚天-to[TO[TO...]]接收者,默认为everyone-p是否加感叹号,好学'''