Python命令行参数的解析

通常,我们运行 Python 项目或者脚本采用直接执行脚本的方式,但是 Python 作为一个脚本语言,在 Linux 中经常会结合 Shell 脚本使用,这个时候执行的 Python 脚本多半需要使用命令行参数传入一些变量,以更加灵活、动态地传递一些数据。

例如,运行命令:

python argv.py 1 2 3

其中1 2 3就是传递给 argv.py 的命令行参数,也就是说命令行参数是调用某个程序时除程序名外的其他参数。

命令行参数工具是常用的工具,它给使用者提供了友好的交互体验。

例如,当我们需要经常调节参数的时候,如果参数都是通过硬编码写在程序中的话,我们每次修改参数都需要修改对应的代码和逻辑,这显然不太方便。比较好的方法是把必要的待修改的参数设置成通过命令行参数传入的形式,这样我们只需要在运行的时候修改参数即可。因此,在使用 Python 开发脚本,并需要接受用户参数运行时,我们可以使用命令行传参的方式。

Python 命令行参数解析库

Python 的命令行参数解析模块主要分为两类,一种是 Python 内置的模块,主要包括 sys.argv、argparse 和 getopt,另一种是第三方模块,比较有名的是 click 模块,如图1所示。


图1:Python 命令行参数解析模块

下面我们将简要阐述对比各模块,如表1所示,然后简单解释解析命令行参数的原理,方便大家进一步理解。

表1:命令行参数解析模块
模块 描述
sys.argv sys.argv 模块传入参数的方式比较简单,功能也比较少,该模块比较适合参数数量很少且固定的脚本。
argparse argparse 模块可以让开发人员轻松地编写用户友好的命令行接口,argparse 模块会自动生成帮助和使用手册,并在用户给程序传入无效参数时报出错误信息。
getopt getopt 模块相比 sys.argv 模块,支持长参数和短参数,以及对参数解析赋值,有很多的高级用法,因此掌握 getopt 模块相对复杂,学习成本高。
click click 模块相比其他模块的优势就是支持多个命令的嵌套和组合,可以快速构建命令行程序,但是在扩展性上就没有 argparse 模块好,需要额外安装除 click 模块以外的第三方模块。

argparse模块的使用

本文将着重讲解如何使用 argparse 模块进行命令行参数解析,argparse 模块是 Python 自带的命令行参数解析模块。在程序中定义我们需要的参数,argparse 模块会从 sys.argv 模块解析出这些参数。

使用 argparse 模块的步骤如下:
  • 构建一个参数实例,生成一个命令行参数的对象。
  • 给对象添加一些参数。
  • 从属性中提取传入的参数并使用。

1) 创建一个解析器

通过 argparse 模块中的 ArgumentParser() 方法创建一个 ArgumentParser 对象,ArgumentParser 对象包含将命令行解析成 Python 数据类型所需的全部信息。示例如下:

parse = argparse.ArgumentParser(prog='argument.py',description='编写命令行的示例文件')

ArgumentParser() 方法其他参数如表2所示其中大部分参数不常用到。

表2:ArgumentParser() 方法的参数
参数 描述
prog 程序名,默认为 sys.argv[0]。
usage 描述程序用途的字符串,默认值从添加到解析器的参数生成。
description 在参数帮助文档之前显示的文本。
parents 一个 ArgumentParser 对象的列表,它们的参数应包含在内。
formatter_class 用于自定义帮助文档输出格式的类。
prefix_chars 可选参数的前缀字符集合,默认为-
fromfile_prefix_chars 当需要从文件中读取其他参数时,用于标识文件名的前缀字符集合。
argument_default 参数的全局默认值。
conflict_handler 解决冲突选项的策略(通常不必要)。
add_help 为解析器添加一个-h/--help选项,默认为 True。
allow_abbrev 如果缩写是无歧义的,则允许缩写长选项,默认为 True。

2) 添加参数

给 ArgumentParser 对象添加参数是通过调用 add_argument() 方法完成的。示例如下:
  • parser.add_argument('name',type=str,help='名字') # 添加位置参数(必选)
  • parser.add_argument('age',type=int,help='年龄') # 添加位置参数(必选)
  • parser.add_argument('-s',dest='--sex',type=str,help='性别') # 添加可选参数
parser.add_argument('name',type=str,help='名字') # 添加位置参数(必选)
parser.add_argument('age',type=int,help='年龄') # 添加位置参数(必选)
parser.add_argument('-s',dest='--sex',type=str,help='性别') # 添加可选参数
其中,add_argument() 方法更多的可选参数如表3所示。

表3:add_argument() 方法的参数
参数 描述
name or flags 选项字符串的名字或者列表,如 foo、-f 或 --foo。
action 在命令行使用该参数时采取的基本动作类型。
nargs 应该读取的命令行参数数量。
const 某些 action 和 nargs 要求的常数值。
default 如果命令行中没有出现该参数时,该参数的默认值。
type 命令行参数应该转换的类型。
choices 参数可允许的值的容器。
required 表示该命令行参数是否可以省略(只针对可选参数)。
help 参数的简短描述。
metavar 参数在帮助信息中的名称。
dest 给 parse_args() 返回的对象要添加的属性名称。

此处,我们重点讲解下必选参数、可选参数、默认值、参数类型、可选值、参数数量、参数传递等几个常用功能的设置方法。

① 必选参数

它的定义和函数中的必填参数是一样的,即运行程序必须要的参数。如果不传入,那么程序会报错并提示。

定义必选参数的方法非常简单,我们只需要通过 add_argument() 方法传入参数的名称即可。示例如下:

parser.add_argument('param')

这样就定义了一个名为 param 的参数,我们可以通过 args.param 来访问它。假设需要运行的程序名称为 test.py,那么我们直接执行以下命令即可:

python test.py xxx

其中必选参数直接传入,不需要加上前缀。

② 可选参数

有必选参数当然就有可选参数,可选参数因为可选可不选,所以我们在使用的时候需要在参数前加上标识---

例如,我们的参数名为 param,可以定义成 -param 或者 --param,这两种方式都可以使用,也可以同时使用两种方式。示例如下:

parser.add_argument('-param', '--param')

如果要给这个可选参数一个解释或提示,方便其他人理解这个参数,那么我们可以加 help,示例如下:

parser.add_argument('-param', '--param', help='this is a param of name')

③ 默认值

如果参数很多,我们可能不希望每一个都指定一个值,而是希望可以在不指定值的时候有一个默认值。我们可以通过 default 参数实现这个需求。示例如下:

parser.add_argument('-param', '--param', default=3, help='this is a param of num')

④ 参数类型

我们可以定义参数的默认值,也可以定义它的类型。因为命令行传入的参数默认都是字符串类型,如果我们要进行数学计算,使用字符串类型还需要先转换,这很不方便。我们可以在传入参数的时候就完成类型的匹配,这样传入参数的类型不对将直接报错,不继续运行程序。

我们可以通过 type 参数实现这个需求。示例如下:

parser.add_argument('-param', '--param', default=3,type=int, help='this is a param of num')

⑤ 可选值

可选值很好理解,就是我们希望限制传入参数的范围仅在几个值当中。例如,我们希望传入的值不是 0 就是 1,或者是在某几个具体的值当中,那么可以通过 choices 参数实现这个需求。

choices 参数传入的是一个列表,也就是我们的限制范围。示例如下:

parser.add_argument('-param', '--param', default=3, choices=[2,3,4], type=int, help='this is a param of num')

⑥ 参数数量

nargs 是一个非常有用的参数,可以用来说明传入的参数个数。例如,+表示传入至少1个参数;2表示必须传入2个参数,在程序运行时,这2个参数的值会以列表的形式赋给 param。

parser.add_argument('-param', '--param', nargs=2, type=int, help='this is a param of num')

⑦ 参数传递

dest 参数用于指定后面的参数传递给谁,在 dest 参数定义后的程序中,我们可以使用 dest 指定的参数名获取对应的值。示例如下:
  • parser.add_argument('-param', '--param', dest = 'port')
  • args = parser.parse_args()
  • server_port = args.port # 通过dest参数指定的port获取。
parser.add_argument('-param', '--param', dest = 'port')
args = parser.parse_args()
server_port = args.port # 通过dest参数指定的port获取。

3) 解析参数

通过 parse_args() 方法将参数字符串转换为对象,并将其设为命名空间的属性,返回带有成员的命名空间:

ArgumentParser.parse_args(args=None, namespace=None)

其中,args 表示要解析的字符串列表,默认值从 sys.argv 获取;namespace 用于获取属性的对象,默认值是一个新的空 Namespace 对象。

注意,可选参数的参数和参数值可以作为两个单独参数传入。对于长参数,参数和参数值可以作为单个命令行参数传入,使用=分隔它们;对于短参数,参数和参数值可以拼接在一起。

示例如下:
  • parser = argparse.ArgumentParser(prog='PROG')
  • parser.add_argument('-x')
  • parser.add_argument('--foo')
  • parser.add_argument('bar')
  • print(parser.parse_args(['--foo=FOO', '-xX', 'bar']))
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-x')
parser.add_argument('--foo')
parser.add_argument('bar')
print(parser.parse_args(['--foo=FOO', '-xX', 'bar']))
另外,当短参数看起来像负数时,解析器会将命令行中所有的负数参数解析为短参数。

位置参数只有在是负数并且解析器中没有任何参数看起来像负数时,才能以-开头。如果必须使用以-开头的位置参数,我们可以插入伪参数--告诉 parse_args() 在那之后的内容是位置参数。示例如下:
  • parser = argparse.ArgumentParser(prog='PROG')
  • parser.add_argument('-1', dest='one')
  • parser.add_argument('foo', nargs=1)
  • parser.add_argument('bar', nargs=1)
  • print(parser.parse_args(['-1', 'X', '--', '-2', '-3']))
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-1', dest='one')
parser.add_argument('foo', nargs=1)
parser.add_argument('bar', nargs=1)
print(parser.parse_args(['-1', 'X', '--', '-2', '-3']))
图2中展示的是一个综合示例,演示了一个简单登录的验证和提示语。

Python 命令行参数解析综合示例
图2:Python 命令行参数解析综合示例

 

 

出处:https://c.biancheng.net/view/40rtyk8.html

=======================================================================================

Python之命令行参数解析

解析命令行参数模块

Python中由三个内建的模块用于处理命令行参数:
第一个:getopt,只能简单的处理命令行参数

官网资料:https://docs.python.org/2/library/getopt.html#module-getopt
第二个:optparse,功能强大,易于使用,可以方便地生成标准的、符合Unix/Posix 规范的命令行说明。(Python2.7以后弃用,不会继续发展)
官网资料:https://docs.python.org/2/library/optparse.html
第三个:argparse,使其更加容易的编写用户友好的命令行接口。它所需的程序进程了参数定义,argparse将更好的解析sys.argv。同时argparse模块还能自动生成帮助及用户输入错误参数时的提示信息。

官网资料:https://docs.python.org/2/library/argparse.html#module-argparse

getopt

   在运行程序时,可能需要根据不同的条件,输入不同的命令行选项来实现不同的功能。目前常用的由短选项和长选项两种格式。短选项格式为"-"加上单个字母 选项,长选项为"--"加上一个单词。长格式实在Linux下引入的。许多Linux程序都支持这两种格式。在Python中提供了getopt模块很好 的实现了对着两种用法的支持,而且使用简单。

获取命令行参数

Python环境下可以使用sys模块得到命令行参数

复制代码
import getopt
import sys

print(sys.argv)

C:\Users\Administrator\>python 222.py -o t --help cmd file1 file2
['222.py', '-o', 't', '--help', 'cmd', 'file1', 'file2']

# 由此可见,所有命令行参数以空格为分隔符,保存在sys.argv列表中,其中第一个为文件名
复制代码

选项的写法要求:
短格式:"-"号后面要紧跟一个选项字母。如果还有此选项的附加参数,可以用空格分开,也可以不分开。长度任意,可以用引号。
例如:
-o
-o "a b"
长格式:"--"号后面要跟一个单词。如果还有些选项的附加参数,后面要紧跟"=",再加上参数。"="号前后不能有空格。
例如:
--help=file1

如何使用getopt进行参数分析及处理?

第一步:导入sys,getopt模块
第二步:分析命令行参数
第三步:处理结果

复制代码
import getopt
import sys

# print(sys.argv)
def usage():
    print(
"""
Usage:sys.args[0] [option]
-h or --help:显示帮助信息
-m or --module:模块名称   例如:ansible all -m shell -a 'date'
-a or --args:模块对于的参数  例如:ansible all -m shell -a 'date'
-v or --version:显示版本
"""
    )
if len(sys.argv) == 1:
    usage()
    sys.exit()

try:
    opts, args = getopt.getopt(sys.argv[1:], "ho:m:a:", ["help", "output="])   # sys.argv[1:] 过滤掉第一个参数(它是脚本名称,不是参数的一部分)
except getopt.GetoptError:
    print("argv error,please input")

# 使用短格式分析串“ho:m:a:”
 当一个选项只表示开关状态时,即后面不带任何参数时,在分析串中写入选项字符,例如:-h表示获取帮助信息,显示完成即可,不需任何参数
 当一个选项后面需要带附加参数时,在分析串中写入选项字符同时后面加一个“:”号,例如:-m表示指定模块名称,后面需加模块名称

# 使用长格式分析串列表:["help", "output="]。
长格式串也可以有开关状态,即后面不跟"="号。如果跟一个等号则表示后面还应有一个参数。这个长格式表示"help"是一个开关选项;"output="则表示后面应该带一个参数。
# print(opts)
# print(args)
# 调用getopt函数。函数返回两个列表:opts和args。
# opts为分析出的格式信息,是一个两元组的列表。每个元素为:(选项串,附加参数)。如果没有附加参数则为空串''。
# args为不属于格式信息的剩余的命令行参数。
# 整个过程使用异常来包含,这样当分析出错时,就可以打印出使用信息来通知用户如何使用这个程序。

# 以下部分即根据分析出的结果做相应的处理,并将处理结果返回给用户
for cmd, arg in opts:  # 使用一个循环,每次从opts中取出一个两元组,赋给两个变量。cmd保存选项参数,arg为附加参数。接着对取出的选项参数进行处理。
    if cmd in ("-h", "--help"):
        print("help info")
        sys.exit()
    elif cmd in ("-o", "--output"):
        output = arg
    elif cmd in ("-m", "--module"):
        module_name = arg
    elif cmd in ("-a", "--module_args"):
        module_args = arg
    elif cmd in ("-v", "--version"):
        print("%s version 1.0" % sys.argv[0])
复制代码
复制代码
import getopt  
    import sys  
      
    config = {  
        "input":"",  
        "output":".",  
          
    }  
      
    #getopt三个选项,第一个一般为sys.argv[1:],第二个参数为短参数,如果参数后面必须跟值,须加:,第三个参数为长参数  
    #是一个列表,  
    opts, args = getopt.getopt(sys.argv[1:], 'hi:o:d',   
          [  
            'input=',   
            'output=',   
            'help'  
            ]  
          )  
      
    #参数的解析过程,长参数为--,短参数为-  
    for option, value in opts:  
        if  option in ["-h","--help"]:  
            print """  
            usage:%s --input=[value] --output=[value]  
            usage:%s -input value -o value  
            """  
        elif option in ['--input', '-i']:  
            config["input"] = value  
        elif option in ['--output', '-o']:  
            config["output"] = value  
        elif option == "-d":  
            print "usage -d"  
      
    print config   
# 结果
输入的参数:--input=c:\temp\aa -o c:\temp\output -d
打印的结果:
usage -d
{'input': 'c:\\temp\\aa', 'output': 'c:\\temp\\output'}
复制代码

argparse

 argparse简介

   argparse是Python用于解析命令行参数和选项的标准模块,用于代替已经过时的optparse模块。argparse模块的作用是用于解析 命 令行参数,例如python parseTest.py input.txt output.txt --user=name --port=8080。

argparse讲解

将以下代码保存为prog.py

复制代码
import argparse

parser = argparse.ArgumentParser(description='Process some integers.')   # 首先创建一个ArgumentParser对象
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)')     # 添加--sum则返回所有数之和,否则返回列表中的最大值

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 optional arguments: -h, --help show this help message and exit --sum sum the integers (default: find the max) # 输入正确的参数信息 $ python prog.py 1 2 3 4 4 $ python prog.py 1 2 3 4 --sum 10 # 输入错误的参数信息 $ python prog.py a b c usage: prog.py [-h] [--sum] N [N ...] prog.py: error: argument N: invalid int value: 'a'
复制代码
ArgumentParser对象的参数
prog - The name of the program (default: sys.argv[0])
usage - The string describing the program usage (default: generated from arguments added to parser)
description - Text to display before the argument help (default: none)
epilog - Text to display after the argument help (default: none)
parents - A list of ArgumentParser objects whose arguments should also be included
formatter_class - A class for customizing the help output
prefix_chars - The set of characters that prefix optional arguments (default: ‘-‘)
fromfile_prefix_chars - The set of characters that prefix files from which additional arguments should be read (default: None)
argument_default - The global default value for arguments (default: None)
conflict_handler - The strategy for resolving conflicting optionals (usually unnecessary)
add_help - Add a -h/–help option to the parser (default: True)
每个参数的详细说明:
prog:即运行程序的名称,默认取sys.argv[0]的值,可以修改为指定的名称
usage:指定usage信息的内容及格式,默认是根据你添加的信息自动生成的,可以自定义修改为指定的内容
description:这个程序的功能概述
epilog:在整个帮助信息最后添加的附加信息
parents:用于定义一些公共的信息供子类调用
formatter_class:整个信息的类定义,主要包含三个类,每个类的功能如下:
  • class argparse.RawDescriptionHelpFormatter # 如何显示文本描述
  • class argparse.RawTextHelpFormatter # 如何显示文本描述
  • class argparse.ArgumentDefaultsHelpFormatter # 自定添加参数信息
prefix_chars:自定义参数个前缀类型
fromfile_prefix_chars:指定文件替代命令行输入参数的方式
argument_default:
conflict_handler:检测是否存在相同的参数选项,不加该参数直接报错,添加该参数可以兼容(conflict_handler='resolve') 
add_help:  设置是否显示帮助信息那表之类(默认显示)
复制代码
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help')
args = parser.parse_args()

$ python myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   foo help

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> parser.add_argument('--foo', help='foo help')
>>> parser.print_help()
usage: PROG [--foo FOO]

optional arguments:
 --foo FOO  foo help
复制代码
add_argument()方法    

    格式: ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])

  • name or flags - Either a name or a list of option strings, e.g. foo or -f, --foo.    # 参数选项列表
  • action - The basic type of action to be taken when this argument is encountered at the command line.
  • nargs - The number of command-line arguments that should be consumed.
  • const - A constant value required by some action and nargs selections.
  • default - The value produced if the argument is absent from the command line.
  • type - The type to which the command-line argument should be converted.
  • choices - A container of the allowable values for the argument.
  • required - Whether or not the command-line option may be omitted (optionals only).
  • help - A brief description of what the argument does.
  • metavar - A name for the argument in usage messages.
  • dest - The name of the attribute to be added to the object returned by parse_args().

实际案例讲解

复制代码
# 基本认识,只有就基本框架
import argparse

parser = argparse.ArgumentParser()
parser.parse_args()

# 结果
C:\Users\Administrator\Desktop>python3 getopt_help.py -h
usage: getopt_help.py [-h]

optional arguments:
  -h, --help  show this help message and exit

C:\Users\Administrator\Desktop>python3 getopt_help.py foo
usage: getopt_help.py [-h]
getopt_help.py: error: unrecognized arguments: foo

C:\Users\Administrator\Desktop>python3 getopt_help.py -f
usage: getopt_help.py [-h]
getopt_help.py: error: unrecognized arguments: -f

# 结果分析
1)不给参数而运行这个程序,将不会得到任何结果
2)没有做任何特别设置,可以得到一个很简洁的帮助信息(第二三个例子)
3)无需人为设置--help参数,就能得到一个良好的帮助信息。但是若给其他参数(比如foo)就会产生一个错误。
复制代码

 其他

 if len(sys.argv) == 1:
     parser.print_help()
     sys.exit(1)

 

 

【出处】:https://www.cnblogs.com/madsnotes/articles/5687079.html

=======================================================================================

个人测试

我自己的测试案例:

import argparse

def get_args():
    parser = argparse.ArgumentParser(prog='argument.py',description='编写命令行的示例文件')
    parser.add_argument('name',type=str,help='名字') # 添加位置参数(必选)
    parser.add_argument('age',type=int,help='年龄') # 添加位置参数(必选)
    parser.add_argument('-s',dest='sex',type=str,help='性别') # 添加可选参数
    args = parser.parse_args()
    print(args)
    print('-----------------')
    print(args.sex) # 通过dest参数指定的sex获取。
    print(args.name)


def get_args1():
    parser = argparse.ArgumentParser()
    parser.add_argument('-b', '--batch_size', type=int, default=64, help='batch size help')
    parser.add_argument('-i', '--image_directory', type=str, default='FGNET/images')
    parser.add_argument('-ls', '--leave_subject', type=int, default=1)
    parser.add_argument('-lr', '--learning_rate', type=float, default=0.001)
    parser.add_argument('-e', '--epoch', type=int, default=100)
    parser.add_argument('-r', '--resume', type=str, default=None)
    parser.add_argument('-K', '--K', type=int, default=6)
    return parser.parse_args()

class ObjectConfiger(object):
    def __init__(self,config):
        self.config = config

    def __getattr__(self, item):
        if item in self.config:
            return self.config[item]
        else:
            raise AttributeError


if __name__ == '__main__':
    print('hello')
    print('===========================')
    parg=get_args()
    # parg=get_args1()
    print(parg)

    configer = ObjectConfiger({
        'boy':{
            'name': '岳云鹏',
            'age' : 5,
            'school': '北极光第五中学'
        },
        'student':{
            '__extends__':['boy'],
            'school': '庞各庄大学',
            'score': 30
        }
    })
    print(configer.get_selection('boy'))
    # 输出 {'name': '岳云鹏', 'age': 5, 'school': '北极光第五中学'}
    
    print(configer.get_selection('student'))
    # 输出

 

posted on 2024-01-31 20:29  jack_Meng  阅读(59)  评论(0编辑  收藏  举报

导航