python接受命令行参数:About argparse module

 

这是一篇argparse入门级教程,如果您已对argparse有部分了解,这篇博文不适合您,无需在这里浪费时间。

 

##速查目录

1.創建對象argparse.ArgumentParser() 有一個description參數對程序進行介紹

2.增加參數parser.add_argument()

3.解析參數parser.parse_args()

4.添加衝突組parser.add_mutually_exclusive_group()

 

##add_parse_args參數說明

1.-參數縮寫,--參數全稱

2.help 參數說明(string)

3.action (string)可以當一個flag使用

    為store_true時會對參數進行bool賦值

    為count時,會根據參數個數為其進行int賦值 如-v就是1,-vv就是2等。不指定會None

4.default,在不指定參數時會被賦值,可以和count聯合起來使用

5.type 指定接受的參數類型(該是什麼類型就是什麼類型)

6.choices (list)指定optional argument可選範圍
 

之所以把它写在前面就是为了让它能起到速查的效果。笔记用的是繁体,我就不修改了,联系前后文差不多也能看懂(也当做锻炼你识别繁体能力的手段)。

 

进入正题。很多时候,我们需要提供一个很好的命令行接口,简化程序交互的同时,也要方便用户的使用。说的大白话一点,就是程序如何简单优雅地处理命令行参数。

 

我猜你第一想到的就是sys.argv,虽然不经常使用,但是很清楚它能够解决问题。

 

编辑脚本代码wowotou.py(这个文件的名字后面说明):

import sys

print(sys.argv)

 

在当前目录下打开命令行嵌入:python wowotou.py -h hello world

                             

程序返回一个list,而其中的items是命令中“python”之后的所有被分隔开的“参数”。“wowotou.py”是第一个,“-h”是第二个以此类推。

 

当我们在程序中需要使用这些参数的时候,就可以通过列表取下标的方法来调用参数。例如sys.argv[0],sys.argv[1]等等。

 

在简单的程序处理中,这种应对方式完全可以胜任。当程序设计稍微一复杂时,这种方式就显得不那么的尽人意。

 

比如,程序需要接受一个x值,一个y值,加一个半径r值。来求得一个圆的面积(我知道坐标没啥用,在举例子嘛)。

 

程序中你可能会这样写:

answer = sys.argv[2] * 2 * math.PI

 

好像没有什么问题呀?的确,但是你认为的正确是理所当然了。

 

这个程序的成功执行,是在用户必须知道他输入的第一个参数是x的值,第二个参数是y的值等等诸如此类增加记忆负担的词。简单点说,就是你要求用户记住你程序接受参数的顺序,还不能出错。

 

来看看argparse是怎么优化的吧,学完后,你可能就会放弃sys.argv了。

 

argparse同样也是标准库,不需要再次下载。

 

我们将代码清空:

                                    

一般情况下,python程序不会对文件之后的任何参数进行处理。当你导入argparse时:

import argparse

parser = argparse.ArgumentParser() //创建解析器对象

parser.parse_args() //解析命令行参数

print("嘿嘿")

(get到两个基础的方法)

 

                              

首先程序运行wowotou文件就无须多讲了。当我们在其之后多加入一个-h参数的时,输出了一些解释信息,其中的optional arguments(可选参数)解释了-h参数的含义“show this help message and exit”。如果我们将其换为--help,会得到同样的结果。

 

这里的-h和--help有什么区别呢?emmm,一个是缩写,一个是全写。这里先做了解,我们会慢慢的深入解释。

 

还有一点,在创建解析器对象的时候,可以添加一个参数description(value为string类型),看单词就能猜个八九不离十(你要是非猜一,那我也没办法),是对参数解释器目标任务的说明。

 

稍加修改:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.parse_args()

print("嘿嘿")

 

                                     

这时再输入相同的命令,就可以查看到你写的信息了。这对用户来说也是个不错的提示方式吧。

 

目前为止,在我们只是简单的引入argparse,并对参数进行解析后。程序可以处理的一个可选参数是-h或--help,这是唯一一个不需要指定的可选参数。那如果指定我们的自定义参数呢?

 

就是速查中的2,使用add_argument()

 

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


print(args.food,",嘿嘿")

 

我们加入了一个指定参数,参数名称为food,对参数的调用可以直接通过解析后的对象使用“.”运算符+变量名来使用。

 

                              

命令行中python wowotou.py之后的第一个参数会被当做food的值(你可以把命令行里的food修改为任意的值)。在程序代码中我们只是添加了一个名称为food的参数,程序会默认把第一个参数当做food的值。例如第二条命令中,除了给予了一个“food”的字符串外,还多给了一个“wowo”字符串。程序会将“food”赋值给food参数,而wowo并不知道怎么处理,就会报错。

 

如果这时使用-h查看帮助信息:

                                           

你会惊奇的发现,除了optional arguments参数列表外,多了一个positional arguments,其中只有一个参数,就是我们指定的参数food。

 

第一个点,关于positional arguments的翻译。我习惯性的说成“位置参数”,有些编程书上翻译为“按位实参”。这个名称更多的会出现在函数里。比如function(value1, value2, key=value3)中,value1和value2都被称为positional argument,而key更习惯的称为关键词实参。

 

第二个点,关于argument和parameter的理解。我们知道,两个词都有参数的意思,区别点在于一般argument指实参,parameter指形参。

 

说了这么多,也只是为了帮助你理解positional arguments这个词的含义。选择你喜欢的翻译方式吧。

 

在argparse中,简单说,位置参数就是必须指定(给予)的参数,即在命令行中必须提供的参数。

 

                    

如果没给,模块就会提示你需要一个值,为名称是food的参数赋值。

 

从这里引入optional arguments,我们知道-h参数是属于这个类别的,而且它和positional arguments的区别就是,这个参数可给可不给。就像我们直接执行python + 文件名,程序也可以正常运行。而不像food参数,不给就会报错。

 

下个问题,那,我们如何制定自己的可选参数?

 

很简单,参数名前加-或者--。(-和--的区别前面已经说明)

 

稍加修改:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("-w")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

print(",嘿嘿")

这时再打开帮助信息:

                                       

自定义的可选参数就被加入到optional arguments的行列中。和-h参数的说明一对比,我们的-w显得特别骨感。再修改:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("-w", "--wowotou", help="a food named wowotou")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

print(",嘿嘿")

                                     

对比着,我们也就知道了全称是怎么设计出来的,以及-h后面的"show this help message and exit"的信息是怎么显示出来的了。

 

到目前为止,我们还没能做出一点能看的东西。别急,先来看add_argument的第一个关键字参数action。

 

这篇文章中,action只有两个value(string 类型),一个store_true,另一个是count。先来说store_true。

 

当action为store_true时,会根据命令行中参数的有无来对参数进行bool赋值。

 

什么意思呢?

 

比如:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

if args.wowotou:
    print("窝窝头,一块钱四个,嘿嘿")

我们对-w参数添加了store_true的action参数。当这个参数为true时,print一条语句,否则什么都不做。

 

(通过args解析对象调用参数,必须是那个全称的名字,即必须是args.wowotou,而不能是args.w)

 

                                      

不给参数的时候,all is well。

 

给了-w参数,成功输出,--wowotou同上。

 

通过这个例子,我们就晓得了store_true的功能了,当命令行中提供了这个可选参数,就会将其置为true,否则置为false。

 

嘿嘿,好像开始有趣了。继续吧。

 

我现在不想卖窝窝头了,我想卖大馒头。我们再将food参数加回来:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food", help="a name of food")

##parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


##if args.wowotou:
##    print("窝窝头,一块钱四个,嘿嘿")

print(args.food,"一块钱四个,嘿嘿")

我们知道,positional arguments是必须给的,而参数的值,就是你命令行中的值。如上:

                                 

给food参数的赋值是大馒头。

 

到此,我们通过位置参数得到售卖的商品,而用可选参数执行某些操作。

 

当职位提升后,我就可以制定价格了,比如一块钱一个,一块钱两个等等。

 

很简单,再添加一个位置参数接收个数。

 

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food", help="a name of food")

parser.add_argument("num", help="how many can I buy for one dollar")

##parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


##if args.wowotou:
##    print("窝窝头,一块钱四个,嘿嘿")

print(args.food,"一块钱",args.num,"个,嘿嘿")

                                        

水面风平浪静,一般海底都波涛汹涌。

 

经理知道你擅自修改数据后,很生气,在程序里面对你的值进行了修改。

 

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food", help="a name of food")

parser.add_argument("num", help="how many can I buy for one dollar")

##parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


##if args.wowotou:
##    print("窝窝头,一块钱四个,嘿嘿")

print(args.food,"一块钱",args.num - 1 ,"个,嘿嘿")

最后在print的时候,将你的args.num减了一个。好像没什么问题吼~

 

                        

再次执行出错了,原因是程序通过命令行接受的参数类型只有一种类型,就是string。

 

两种方法解决,得到数据后,对数据进行类型转换。弊端,接收到的string(用户输入的,具有主观性)并不一定能转换成你想要的类型。(比如将“hahaha”转换成int类型)

 

这时,可以使用一个参数type来指定你想要接受的类型:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food", help="a name of food")

parser.add_argument("num", type=int, help="how many can I buy for one dollar")

##parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


##if args.wowotou:
##    print("窝窝头,一块钱四个,嘿嘿")

print(args.food,"一块钱",args.num - 1 ,"个,嘿嘿")

我们在num参数中加入了type参数,来告诉程序,我要的num参数的值是个int类型。这时:

                                         

完美执行了。那如果用户给的不是int类型呢?

                            

会告诉你,这是个无效的int值。如此,用户就知道了,我这里需要给个整数。

 

在你得知经理不满后,主动认错。经理也退让了一步,同意你指定价格,不过要在他规定的范围内。引入下一个参数choices,这个参数的类型是list。

 

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food", help="a name of food")

parser.add_argument("-n", "--num", type=int, help="how many can I buy for one dollar", choices=[1,2,3,4])

##parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


##if args.wowotou:
##    print("窝窝头,一块钱四个,嘿嘿")

print(args.food,"一块钱",args.num,"个,嘿嘿")

我们将num改为可选参数,并加入了choices。现在num参数的给定值,就只能在choices范围里面挑了:

  

而当你超出范围时,就会警告你,并告诉你范围集。

 

继续继续。

 

我们再将程序修改一下,介绍下一个参数,default:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("-f","--food", help="the name of food", default="窝窝头")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

print(args.food,"一块钱四个,嘿嘿")

将food参数修改为optional argument,并加入default参数赋值string类型“窝窝头”。

 

在不指定-f参数的情况下,会默认赋值“窝窝头”,在给定参数的情况下,会覆盖掉默认参数。

 

如:

                                   

代码中default被赋值了字符串类型的常量,你可以赋值任何你想要类型。甚至是一个函数(如max,min等等)。

 

致此,还有一个点没有说到,就是action的count行为。我是认为,这个count可以作为一种等级处理。

 

举个例子,你摆小摊卖窝窝头,有被没收小推车的风险。我们创建一个参数w代表warning。并用count来表示warning的等级。

 

show code:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("-w","--warning", action="count", default=0)

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

print(args.warning)

if args.warning == 0:
    print("淡定,没事~")
elif args.warning == 1:
    print("我现在内心有点慌。。。")
elif args.warning == 2:
    print("时刻准备着---")
else:
    print("跑!")

count的行为,会计算命令行中此参数的出现次数,无论是缩写还是全称。(为了便于演示,在执行判断之前,我们把参数值输出一下。)

 

直接看使用吧:

                               

对比一下,很容易就能理解。

 

(这里有一个点,需要说明,当action="count"和default=一个整数同时使用的时候。最终参数的值是default的值加上count的计数值。比如你的default=1,在命令行中参数出现次数为1的时候,程序中这个参数的值就是2。如果default是3,那值为4。)

 

还有一个函数:add_mutually_exclusive_group()

 

函数名直译就是“添加相互独立组”,这个是干什么用的呢?其实就是限制某些参数同时出现,举个例子,你不能同时卖“窝头”和“馒头”。如果我们用w代表窝头,m代表馒头,那参数w和m不能同时出现。

 

这个函数就是干这件事用的。

import argparse

parser = argparse.ArgumentParser("What are you selling?")

group = parser.add_mutually_exclusive_group()

##将w和m参数加入到同一个冲突组中
group.add_argument("-w","--wowotou", action="store_true")
group.add_argument("-m", "--mantou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

if args.wowotou:
    print("窝窝头,一块钱四个,嘿嘿")
elif args.mantou:
    print("大馒头,一块钱四个,嘿嘿")

使用示例:

    

在参数w和m同时出现时,就会对你发出警告,m参数不允许和参数w一起出现。

 

全部的入门内容已经讲述完毕了,剩下最后一个伏笔没有解释。那就是对文件名“wowotou”的含义说明,不过现在看来,已经没那个了。

发布了53 篇原创文章 · 获赞 80 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_41500251/article/details/102810176