Python 命令行参数

optparse模块已弃用,与optparse相比较,argparse的API类似于optparse,甚至在很多情况下通过更新所使用的类名和方法名,使用argparse作为一个简单的替代。然而,有些地方在添加新特性时不能保持直接兼容性。

Python脚本传参的三种方式(sys.argv、argparse、tf.app.flags)

如果在运行python脚本时需要传入一些参数,可以使用如下方式。

python script 0,1,2 10
python script -gpus=0,1,2 --batch-size=10
python script -gpus=0,1,2 --batch_size=10

这三种格式对应不同的参数解析方式,分别为

前两者是python自带的功能,后者是tensorflow提供的便捷方式。

1. python的sys.argv

sys模块是很常用的模块, 它封装了与python解释器相关的数据,例如sys.modules里面有已经加载了的所有模块信息,sys.path里面是PYTHONPATH的内容,而sys.argv则封装了传入的参数数据。

使用sys.argv接收上面第一个命令中包含的参数方式如下:

import sys
gpus = sys.argv[1]
#gpus = [int(gpus.split(','))]
batch_size = sys.argv[2]
print(gpus)
print(batch_size)

python3 demo.py 123 321
123
321

2. python的argparse包

argparse是python的命令行解析工具,可以在python代码中调用shell的一些命令。程序内部定义了需要使用的参数,argparse 会默认自动从 sys.argv中解析出对应的参数。argparse模块会自动生成帮助信息和使用提示,同时当用户使用无效参数时,会显示错误原因。

tensorflow的一些例子中用argparse来定义一些默认命令,通常是全局变量,也是用作和系统命令之间交互的全局设置。

【argparse官网】https://docs.python.org/3.6/library/argparse.html

2.1 argparse的基本用法

下面一个实例展示了argparse的基本使用方法:

import argparse 

# 创建一个参数解析实例
parser = argparse.ArgumentParser(description='Parameters') 

# 添加参数解析
parser.add_argument('--training_epoch', type=int, default=3000)
parser.add_argument('--learning_rate', type=float, default=0.001)
parser.add_argument('--model_name', type=str, default='lstm')

# 开始解析
# pycharm: args = parser.parse_args()
# jupyter: args = parser.parse_args(args=[])
args = parser.parse_args(args=[]) 

# 输出参数
print({args})
print(args.training_epoch)
print(args.learning_rate)
print(args.model_name)
# 参数的使用
epochs = args.training_epoch
lr = args.learning_rate
model = args.model_name

2.2 ArgumentParser.add_argument()传参

add_argument()方法的基本定义如下:

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

相关参数的含义如下:

2.3 add_argument()传参为list类型

argparse的parser.add_argument()函数中传入参数的type为常见的类型,如int,str,float等。

# nargs=3 限制该参数只能有3个输入
# required=True 该参数为必须输入项;required=False 该参数为可选输入项
parser.add_argument('--test_data', type=int, nargs=3, required=True) 

test_data = args.test_data
print('test_data:', test_data)

在控制台下运行如下命令:

python main.py --test_data 1 2 3

可以看到 test_data 的输出结果为

# test_data: [1, 2, 3]

假设我们想给 test_data 输入多个参数,则可以使用 “nargs=‘+’”,如下所示:

# nargs='+' 该参数可以有多个输入
parser.add_argument('--test_data', type=int, nargs='+', required=True)
test_array = np.array(test_data)   # 将传入的list转为array类型
test_array_new = test_array.reshape(-1, 3, 1)
print('test_array_new:', test_array_new)  
# test_data: [[[1] [2] [3]]]

到这里,就得到了我们所需要的shape为(-1, 3, 1)的array,再将array作为入参传入我们Python的函数中即可。

【补充】:更多 list 类型参数的传入,可以参考博客:

3. tf.app.flags组件

在Tensorflow中,还可以使用flags定义命令行参数。

3.1 tf.app.flags的基本用法

tf定义了tf.app.flags,用于接受命令行传递参数,相当于接受argv。首先调用自带的DEFINE_integer,DEFINE_float, DEFINE_string 等设置不同类型的命令行参数及其默认值。当然,也可以在终端用命令行参数修改这些默认值。

下面一个实例展示了tf.app.flags的基本使用方法:

import tensorflow as tf

flags = tf.app.flags
FLAGS = tf.app.flags.FLAGS
flags.DEFINE_integer('training_epoch', 3000, 'number of epochs to train.')
flags.DEFINE_float('learning_rate', 0.001, 'Initial learning rate.')
flags.DEFINE_string('model_name', 'lstm', 'model name')

def main(_):
    # 输出参数
    print(FLAGS.training_epoch)
    print(FLAGS.learning_rate)
    print(FLAGS.model_name)
if __name__ == '__main__':
    tf.app.run()  #执行main函数 
# 参数的使用
epochs = FLAGS.training_epoch
lr = FLAGS.learning_rate
model = FLAGS.model_name

4. 设置参数运行.py脚本

虽然我们在样例代码中指定了argparse和tf.app.flags的默认参数,但是在实际运行中如果想传入自定义的参数,可以通过命令行模式和pycharm的IDE模式两种方式实现。

假定需要传入的自定义参数为:

training_epoch 为 1000 
learning_rate 为 0.002 
model_name 为 'lstm'

4.1 命令行模式

程序在控制台下运行时格式为:

python test.py --training_epoch 1000 --learning_rate 0.002 --model_name 'lstm'

4.2 pycharm的IDE模式

在pycharm的IDE模式下,我们需要给程序事先指定好输入参数。点击“Run”菜单下的"Edit Configurations…"命令

在Parameters中填入如下参数:

参考博客: