如果在运行python脚本时需要传入一些参数,例如gpus
与batch_size
,可以使用如下三种方式。
0 1 2 |
python script.py 0,1,2 10 python script.py -gpus=0,1,2 --batch-size=10 python script.py -gpus=0,1,2 --batch_size=10 |
这三种格式对应不同的参数解析方式,分别为sys.argv
, argparse
, tf.app.run
, 前两者是python自带的功能,后者是tensorflow
提供的便捷方式。
sys.argv
sys
模块是很常用的模块, 它封装了与python解释器相关的数据,例如sys.modules
里面有已经加载了的所有模块信息,sys.path
里面是PYTHONPATH
的内容,而sys.argv
则封装了传入的参数数据。
使用sys.argv
接收上面第一个命令中包含的参数方式如下:
0 1 2 3 4 5 |
import sys gpus = sys.argv[1] #gpus = [int(gpus.split(','))] batch_size = sys.argv[2] print gpus print batch_size |
需要模块:sys
参数个数:len(sys.argv)
脚本名: sys.argv[0]
参数1: sys.argv[1]
参数2: sys.argv[2]
test.py
0 1 2 3 4 5 |
import sys print "脚本名:", sys.argv[0] for i in range(1, len(sys.argv)): print "参数", i, sys.argv[i] >>>python test.py hello world |
脚本名:test.py
参数 1 hello
参数 2 world
python中使用命令行选项:
例如我们需要一个convert.py脚本。它的作用是处理一个文件,并将处理后的结果输出到另一个文件中。
要求该脚本满足以下条件:
1.通过-i -o选项来区别参数是输入文件还是输出文件.
>>> python convert.py -i inputfile -o outputfile
2.当不知道convert.py需要哪些参数时,用-h打印出帮助信息
>>> python convert.py -h
getopt函数原形:
getopt.getopt(args, options[, long_options])
convert.py
0 1 2 3 4 5 6 7 8 9 10 11 12 |
import sys, getopt opts, args = getopt.getopt(sys.argv[1:], "hi:o:") input_file="" output_file="" for op, value in opts: if op == "-i": input_file = value elif op == "-o": output_file = value elif op == "-h": usage() sys.exit() |
代码解释:
a) sys.argv[1:]为要处理的参数列表,sys.argv[0]为脚本名,所以用sys.argv[1:]过滤掉脚本名。
b) ”hi:o:”: 当一个选项只是表示开关状态时,即后面不带附加参数时,在分析串中写入选项字符。当选项后面是带一个附加参数时,在分析串中写入选项字符同时后面加一个”:”号。所以”hi:o:”就表示”h”是一个开关选项;”i:”和”o:”则表示后面应该带一个参数。
c) 调用getopt函数。函数返回两个列表:opts和args。opts为分析出的格式信息。args为不属于格式信息的剩余的命令行参数。opts是一个两元组的列表。每个元素为:(选项串,附加参数)。如果没有附加参数则为空串”。
getopt函数的第三个参数[, long_options]为可选的长选项参数,上面例子中的都为短选项(如-i -o)
长选项格式举例:
--version
--file=error.txt
让一个脚本同时支持短选项和长选项
getopt.getopt(sys.argv[1:], "hi:o:", ["version", "file="])
argparse
0 1 2 3 4 5 6 |
import argparse parser = argparse.ArgumentParser(description='manual to this script') parser.add_argument('--gpus', type=str, default = None) parser.add_argument('--batch-size', type=int, default=32) args = parser.parse_args() print args.gpus print args.batch_size |
需要注意的是,脚本运行命令python script.py -gpus=0,1,2 --batch-size=10
中的--batch-size
会被自动解析成batch_size
.
parser.add_argument
方法的type
参数理论上可以是任何合法的类型, 但有些参数传入格式比较麻烦,例如list,所以一般使用bool
, int
, str
, float
这些基本类型就行了,更复杂的需求可以通过str
传入,然后手动解析。bool
类型的解析比较特殊,传入任何值都会被解析成True
,传入空值时才为False
0 1 2 |
python script.py --bool-val=0 # args.bool_val=True python script.py --bool-val=False # args.bool_val=True python script.py --bool-val= # args.bool_val=什么都不写False |
通过这个方法还能指定命令的帮助信息。具体请看API文:https://docs.python.org/2/library/argparse.html
tf.app.run
tensorflow也提供了一种方便的解析方式。
脚本的执行命令为:
0 |
python script.py -gpus=0,1,2 --batch_size=10 |
对应的python代码为:
0 1 2 3 4 5 6 7 8 9 10 11 |
import tensorflow as tf tf.app.flags.DEFINE_string('gpus', None, 'gpus to use') tf.app.flags.DEFINE_integer('batch_size', 5, 'batch size') FLAGS = tf.app.flags.FLAGS def main(_): print FLAGS.gpus print FLAGS.batch_size if __name__=="__main__": tf.app.run() |
有几点需要注意:
tensorflow
只提供以下几种方法:
tf.app.flags.DEFINE_string
,
tf.app.flags.DEFINE_integer
,
tf.app.flags.DEFINE_boolean
,
tf.app.flags.DEFINE_float
四种方法,分别对应str
,int
,bool
,float
类型的参数。这里对bool
的解析比较严格,传入1会被解析成True
,其余任何值都会被解析成False
。- 脚本中需要定义一个接收一个参数的
main
方法:def main(_):
,这个传入的参数是脚本名,一般用不到, 所以用下划线接收。 - 以
batch_size
参数为例,传入这个参数时使用的名称为--batch_size
,也就是说,中划线不会像在argparse
中一样被解析成下划线。 tf.app.run()
会寻找并执行入口脚本的main
方法。也只有在执行了tf.app.run()
之后才能从FLAGS
中取出参数。
从它的签名来看,它也是可以自己指定需要执行的方法的,不一定非得叫main
:run( main=None, argv=None )tf.app.flags
只是对argpars
的简单封装。代码见https://github.com/tensorflow/tensorflow/blob/r1.2/tensorflow/python/platform/flags.py