当我们执行某个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 numberPyTorch MNIST pruning from deep compression paper
positional arguments:
square display a square of a given number
number display a given numberoptional 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。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。