命令行传递参数argparse.ArgumentParser的使用解析

2023-02-17 18:02:18 命令行 解析 传递

当我们执行某个python代码,例如文件mycode.py时,想要传递一些可以随时改变的自定义的参数。

比如在训练神经网络的时候,我们为了方便修改训练的batch大小,epoch的大小等等,往往不想去动代码。

此时最方便的方法就是在执行代码的时候从命令行传入参数。

argparse.ArgumentParser()可以很好地满足这一需求。

1.简单示例   

先看一段简单的代码,在名为mycode.py的文件中

import argparse
 
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number", type=int)
args = parser.parse_args()
print(args.square**2)

改代码首先创建一个ArgumentParser对象,而添加为了参数square,则采用方法parser.add_argument。

每添加一个参数,就需要调用一次该方法。

args = parser.parse_args()则是使得改代码生效。

执行这段代码时,我们在命令行输入

$ Python mycode.py 9

可以得到输出结果是9的平方,即81。

当然,添加多个参数时,执行的时候顺序输入这些参数。

例如mycode.py中是如下代码:

import argparse
 
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number", type=int)
parser.add_argument("number", help="display a given number", type=int)
args = parser.parse_args()
print(args.square**2)
print(args.number)

我们在命令行输入

$ python mycode.py 20 999

可以得到输出结果是

400
999

2.argparse.ArgumentParser():创建对象

argparse.ArgumentParser()可设置的参数挺多,这里只提一下description这一个参数,他是一个自定义文本参数,可以用来描述这个程序是做什么的,也可以随便写点东西,总之,不影响程序的功能,可以看做是个注释。

例如执行下一段代码

parser = argparse.ArgumentParser(description='PyTorch MNIST pruning from deep compression paper')
parser.add_argument("square", help="display a square of a given number", type=int)
parser.add_argument("number", help="display a given number", type=int)
args = parser.parse_args()
print(args.square**2)
print(args.number)
parser.print_help()

其中parser.print_help()的功能是我们创建的parser的相关信息。

命令行输入

$ python mycode.py 20 999

输出结果为

400
999
usage: day1.py [-h] square number

PyTorch MNIST pruning from deep compression paper

positional arguments:
  square      display a square of a given number
  number      display a given number

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

可以看到,description中的文字也得到了输出。

3.parser.add_argument():添加参数

parser.add_argument()可配置的参数比较多,第一个是name,也就是名称。

前面的例子中,我们用了

parser.add_argument("square", help="display a square of a given number", type=int)

其中"square"就是传递给name的参数(也可以单引号的’square’)。

这里还有个help参数,他和argparse.ArgumentParser()中的description类似,没有实际作用,起到一个注释的作用,会在parser.print_help()后打印出来。

而显然type参数指定了输入参数的类型,int是整数,float是浮点,str是字符串

回到name参数,他除了可以直接用上面的square字符串,也可以一个横杠加字符串以及两个横杠加字符串,例如’-sqaure’和’–square’。

常见的是两个横杠的写法。下面来说说我个人发现的区别。

没有横杠的写法,如我们前面所示,在命令行传入参数的时候,不需要重写名字,直接输入参数:

$ python mycode.py 20 999

但是假如使用两个横杠的name,直接传入参数会报错,需要在传入参数的时候重写name。

例如下列代码

parser = argparse.ArgumentParser(description='PyTorch MNIST pruning from deep compression paper')
parser.add_argument("--square", help="display a square of a given number", type=int)
parser.add_argument("--number", help="display a given number", type=int)
args = parser.parse_args()
print(args.square**2)
print(args.number)

命令行执行时需要

$ python mycode.py --square 20 --number 999

另外一个需要提到的点是name的取名时,字符串中的横杠和下划线似乎是等价的。

例如

parser.add_argument('--batch_size', type=int, default=50)

parser.add_argument('--batch-size', type=int, default=50)

是等价的。但是传递参数的时候,name是横杠也得用横杠;name是下划线也得用下划线:

parser.add_argument('--batch_size', type=int, default=50)

$ python mycode.py --batch_size 128

或者

parser.add_argument('--batch-size', type=int, default=50)

$ python mycode.py --batch-size 128

调用的时候统一用下划线:

print(args.batch_size)

个人建议传递name的时候还是用下划线别用横杠,方便查找。

这里default用于定义没有传递参数时,该参数的默认值。

需要注意的是,name参数用横杠的名称的时候设置default值,命令行执行程序的时候可以不传入参数或者传入部分参数,没传入的参数使用默认值;name参数用没有横杠的名称的时候,必须传入参数。

下面的parser.add_argument()用到了action参数:

parser.add_argument('--no-cuda', action='store_true',help='disables CUDA training')

action='store_true’表示如果我们在命令行配置这个参数,则该参数为True;不配置则默认为False。

类似的action='store_false’表示如果我们在命令行配置这个参数,则该参数为False;不配置则默认为True。

配置action类型的参数不需要传入具体的数值或者字符串,例如上例中,只需要

$ python mycode.py ----no-cuda

则表示对该参数进行了配置,他会被设为True。

metavar参数只对用parser.print_help()打印参数信息的时候会有影响,并不影响程序的其他功能。

例如

parser = argparse.ArgumentParser(description='PyTorch MNIST pruning from deep compression paper')
parser.add_argument('--batch_size', type=int, default=50, 
                    help='input batch size for training (default: 50)')
args = parser.parse_args()
parser.print_help()

打印结果为

usage: day1.py [-h] [--batch_size BATCH_SIZE]

PyTorch MNIST pruning from deep compression paper

optional arguments:
  -h, --help            show this help message and exit
  --batch_size BATCH_SIZE
                        input batch size for training (default: 50)

假如设置metavar参数:

parser = argparse.ArgumentParser(description='PyTorch MNIST pruning from deep compression paper')
parser.add_argument('--batch_size', type=int, default=50, metavar='N',
                    help='input batch size for training (default: 50)')
args = parser.parse_args()
parser.print_help()

打印结果为

usage: day1.py [-h] [--batch_size N]

PyTorch MNIST pruning from deep compression paper

optional arguments:
  -h, --help      show this help message and exit
  --batch_size N  input batch size for training (default: 50)

可见,只是改变了一些参数的显示。

为传递多个参数,可以用nagrs。当nargs为1时,有且只能传入一个参数:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--one', nargs=1, required=True)
args = parser.parse_args()
print(args.one)

输出

$ python mycode.py --one  1
$ ['1']

当nargs为其他数值,例如3时,表示必须传入3个参数:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--three', nargs=3, required=True)
args = parser.parse_args()
print(args.three)

输出

$ python mycode.py --three  1 2 3
$ ['1', '2', '3']

当设置了nargs参数,则输出是一个list。

dest参数可以改变argparse.ArgumentParser()对应的参数调用时候的名称。

例如下面这一段

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.accumulate(args.integers))

如果第二个参数没有dest=‘accumulate’,则在调用的时候,最后一行代码只能是

print(args.sum(args.integers))

dest使得它在调用的时候被改名。但要注意在命令行传入参数的时候仍然是用name的字符串,即–sum。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

相关文章