Python 命令行参数提供了一种方便的方式,在运行程序时从命令行接受一些信息。我们通常会在 Python 脚本名称后附加这些值。
为了运行一个 Python 程序,我们在操作系统的命令提示终端执行下列命令。例如,在 Windows 中,会在 Windows 命令提示终端输入如下命令:
$ python script.py arg1 arg2 arg3
这里 Python 脚本名称是 script.py
,其余三个参数 arg1 arg2 arg3
是程序的命令行参数。
如果程序需要从用户那里接收输入,Python 的 input()
函数会被使用。当程序从命令行执行时,用户输入会从命令终端获得。
示例
name = input("Enter your name: ")
print ("Hello {}. How are you?".format(name))
程序从命令提示终端运行如下:
command prompt
执行时传递参数
很多时候,您可能需要直接在命令行中放置程序要使用的数据,并在程序内部使用它。在 Windows 中给予数据的一个例子可以是任何 DOS 命令,或者在 Linux 中的命令。
在 Windows 中,您使用下列 DOS 命令将文件 hello.py
重命名为 hi.py
:
C:\Python311>ren hello.py hi.py
在 Linux 中您可以使用 mv
命令:
$ mv hello.py hi.py
这里 ren
或 mv
是需要旧文件名和新文件名的命令。由于它们与命令排成一行,因此它们被称为命令行参数。
您可以从命令行向 Python 程序传递值。Python 会将这些参数收集到一个列表对象中。Python 的 sys
模块通过 sys.argv
变量提供了对任何命令行参数的访问。sys.argv
是命令行参数的列表,sys.argv[0]
是程序即脚本名称。
示例
hello.py
脚本使用 input()
函数在脚本运行后接受用户输入。让我们将其改为从命令行接受输入。
import sys
print ('argument list', sys.argv)
name = sys.argv[1]
print ("Hello {}. How are you?".format(name))
从命令行运行程序如下图所示:
command-line
输出如下:
C:\Python311>python hello.py Rajan
argument list ['hello.py', 'Rajan']
Hello Rajan. How are you?
命令行参数总是存储在字符串变量中。为了作为数值使用它们,可以通过类型转换函数适当地解析它们。
示例
在下面的例子中,两个数字作为命令行参数传入。在程序内部,我们使用 int()
函数将它们解析为整数变量。
import sys
print ('argument list', sys.argv)
first = int(sys.argv[1])
second = int(sys.argv[2])
print ("sum = {}".format(first+second))
它将产生以下输出:
C:\Python311>python hello.py 10 20
argument list ['hello.py', '10', '20']
sum = 30
Python 的标准库包含几个有用的模块来解析命令行参数和选项:
-
-
argparse
— 命令行选项、参数和子命令的解析器。
学习 Python 的 getopt 模块
Python 提供了一个 getopt
模块,可以帮助您解析命令行选项和参数。此模块提供了两个函数和一个异常来启用命令行参数的解析。
getopt.getopt()
方法
此方法解析命令行选项和参数列表。以下是此方法的简单语法:
getopt.getopt(args, options, [long_options])
参数详情如下:
-
-
options
— 脚本想要识别的选项字母字符串,需要参数的选项后面应该跟着一个冒号(":")。
-
long_options
— 可选参数,如果指定,必须是一串长选项名称,这些选项应当被支持。需要参数的长选项后面应该跟着等号('=')。如果只想接受长选项,则 options
应该是一个空字符串。
此方法返回由两部分组成的值 — 第一部分是一个包含 (option, value) 对的列表,第二部分是去除了选项列表后剩余的程序参数列表。
返回的每个选项及其值对都以选项作为其第一元素,短选项前缀有一个连字符(如 -x
),长选项前缀有两个连字符(如 --long-option
)。
异常 getopt.GetoptError
当在参数列表中找到未识别的选项,或者需要参数的选项未给出参数时,会引发此异常。
异常的参数是一个指示错误原因的字符串。属性 msg
和 opt
给出了错误消息和相关的选项。
示例
假设我们想通过命令行传递两个文件名,并且还想给出一个检查脚本用法的选项。脚本的用法如下:
usage: test.py -i <inputfile> -o <outputfile>
下面是测试脚本 test.py
:
import sys, getopt
def main(argv):
inputfile = ''
outputfile = ''
try:
opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="])
except getopt.GetoptError:
print ('test.py -i <inputfile> -o <outputfile>')
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print ('test.py -i <inputfile> -o <outputfile>')
sys.exit()
elif opt in ("-i", "--ifile"):
inputfile = arg
elif opt in ("-o", "--ofile"):
outputfile = arg
print ('Input file is "', inputfile)
print ('Output file is "', outputfile)
if __name__ == "__main__":
main(sys.argv[1:])
现在,按如下方式运行上述脚本:
$ test.py -h
usage: test.py -i <inputfile> -o <outputfile>
$ test.py -i BMP -o
usage: test.py -i <inputfile> -o <outputfile>
$ test.py -i inputfile -o outputfile
Input file is " inputfile
Output file is " outputfile
Python argparse 模块
argparse
模块提供了编写非常易于使用的命令行界面的工具。它可以处理如何解析 sys.argv
列表中收集的参数,自动生成帮助,并在给出无效选项时发出错误消息。
设计命令行界面的第一步是设置解析器对象。这是通过 argparse
模块中的 ArgumentParser()
函数完成的。该函数可以给定一个描述性的字符串作为描述参数。
首先,我们的脚本将从命令行无任何参数地执行。仍然使用解析器对象的 parse_args()
方法,但由于没有任何参数,所以它实际上什么也不做。
import argparse
parser = argparse.ArgumentParser(description="样本参数解析器")
args = parser.parse_args()
当上面的脚本运行时:
C:\Python311>python parser1.py
C:\Python311>python parser1.py -h
usage: parser1.py [-h]
样本参数解析器
options:
-h, --help show this help message and exit
第二个命令行使用 -help
选项,这会产生如上所示的帮助信息。-help
参数默认可用。
现在让我们定义一个对于脚本运行来说是必需的参数,并且如果没有给出,脚本应该抛出错误。在这里我们通过 add_argument()
方法定义了 'user' 参数。
import argparse
parser = argparse.ArgumentParser(description="样本参数解析器")
parser.add_argument("user")
args = parser.parse_args()
if args.user == "Admin":
print ("Hello Admin")
else:
print ("Hello Guest")
此脚本的帮助现在显示了一个形式为 'user' 的位置参数。程序检查其值是否为 'Admin' 并打印相应的消息。
C:\Python311>python parser2.py --help
usage: parser2.py [-h] user
样本参数解析器
positional arguments:
user
options:
-h, --help show this help message and exit
使用以下命令:
C:\Python311>python parser2.py Admin
Hello Admin
但是以下使用显示了 Hello Guest 消息。
C:\Python311>python parser2.py Rajan
Hello Guest
add_argument()
方法
我们可以在 add_argument()
方法中为参数分配默认值。
import argparse
parser = argparse.ArgumentParser(description="样本参数解析器")
parser.add_argument("user", nargs='?', default="Admin")
args = parser.parse_args()
if args.user == "Admin":
print ("Hello Admin")
else:
print ("Hello Guest")
这里 nargs
表示应消耗的命令行参数的数量。'?'.
如果可能的话,从命令行中消耗一个参数,并作为一个单独的条目生成。如果没有命令行参数存在,则生成来自 default
的值。
默认情况下,所有参数都被视为字符串。为了明确指出参数的类型,使用 type
参数在 add_argument()
方法中指定。所有 Python 数据类型都是 type
的有效值。
import argparse
parser = argparse.ArgumentParser(description="加法")
parser.add_argument("first", type=int)
parser.add_argument("second", type=int)
args = parser.parse_args()
x = args.first
y = args.second
z = x + y
print ('{} 和 {} 的加法结果为 {}'.format(x, y, z))
它将产生以下输出:
C:\Python311>python parser3.py 10 20
10 和 20 的加法结果为 30
在上面的例子中,参数是必需的。为了添加可选参数,用双破折号 --
前缀其名称。在下面的情况下 surname
参数是可选的,因为它前面有双破折号 --
。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("name")
parser.add_argument("--surname")
args = parser.parse_args()
print ("我的名字是 ", args.name, end=' ')
if args.surname:
print (args.surname)
C:\Python311>python parser3.py Anup
我的名字是 Anup
C:\Python311>python parser3.py Anup --surname Gupta
我的名字是 Anup Gupta
如果希望参数值仅来自定义的列表,可以将其定义为 choices
参数。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("sub", choices=['Physics', 'Maths', 'Biology'])
args = parser.parse_args()
print ("我的科目是 ", args.sub)
请注意,如果参数值不在列表中,将显示无效选择错误。
C:\Python311>python parser3.py Physics
我的科目是 Physics
C:\Python311>python parser3.py History
usage: parser3.py [-h] {Physics,Maths,Biology}
parser3.py: error: argument sub: invalid choice: 'History' (choose from
'Physics', 'Maths', 'Biology')