想知道如何在执行 Python 脚本时运用命令行参数吗?本文将深入探讨如何利用 Python 的 sys
、getopt
和 argparse
模块来解析这些参数。
在 Python 中,通常使用 input()
函数来接收用户的输入。但是,在某些情境下,你可能需要在通过命令行执行脚本时传递一些特定的参数。
本文将指引你如何在命令行中使用选项和参数来运行 Python 脚本,并展示如何利用 Python 内置的模块来解析这些选项和参数。
让我们开始吧!
理解 Python 中的 sys.argv
如果你熟悉 C 语言编程,你一定知道通过命令行向程序传递参数是一种常见方法。在 C 语言中,通常会这样定义 main
函数:
#include<stdio.h> int main(int argc, char **argv){ //argc: argument count //argv: argument vector //do something on the args return 0; }
这里,argc
代表参数的个数,argv
则代表参数向量。
使用命令行参数运行 Python 脚本
在 Python 中,你可以通过 python3 filename.py
在命令行中运行 Python 脚本。 你还可以在执行脚本时传入任意数量的命令行参数:
$ python3 filename.py arg1 arg2 ... argn
sys
模块为我们提供了直接访问和处理这些命令行参数的支持。sys.argv
是一个列表,其中包含了我们在运行 Python 脚本时传入的所有命令行参数。
下面是一个使用命令行参数运行 main.py
的示例:
$ python3 main.py hello world python script
我们可以通过简单的 for 循环和 enumerate
函数来遍历这个参数向量:
# main.py import sys for idx, arg in enumerate(sys.argv): print(f"arg{idx}: {arg}")
# 输出 arg0:main.py arg1:hello arg2:world arg3:python arg4:script
可以看到,第一个参数(索引为 0)是 Python 文件的名称,后续的参数从索引 1 开始。
这是一个接收并处理命令行参数的最小程序。 但是,我们发现了一些问题:
- 用户如何知道需要传递哪些参数?
- 这些参数代表什么?
这些问题都不是很明确。 为了解决这些问题,你可以使用 getopt
或 argparse
模块,我们将在接下来的部分学习如何使用它们。✅
使用 Python 的 getopt
解析命令行参数
现在,让我们来学习如何使用内置的 getopt
模块来解析命令行参数。
导入 getopt
模块后,你可以定义需要解析的参数以及脚本支持的短选项和长选项。 我们需要解析 sys.argv
中从索引 1 开始的所有参数,所以需要解析的切片是 sys.argv[1:]
。
假设我们需要一个消息字符串和一个文件名。 我们可以使用 m
和 f
作为短选项,message
和 file
作为长选项。
那么如何确保某些选项需要参数呢?
- 对于短选项,可以在短选项名称后添加冒号 (:) 来使其需要参数。
- 对于长选项,可以在长选项名称后添加等号 (=) 来使其需要参数。
结合以上定义,我们在 main.py
中会有以下代码:
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=','file=']) print(opts) print(args)
在这里,变量 opts
包含选项和参数,以元组列表的形式存储。 任何其他的参数(位置参数)都会被收集到 args
变量中。
我们可以通过短选项或长选项传入消息和文件名来运行脚本。
使用长选项运行 main.py
,我们得到:
$ python3 main.py --message hello --file somefile.txt
选项和参数作为元组存储在 opts
变量中。 由于我们没有传递任何位置参数,args
是一个空列表。
# 输出 [('--message', 'hello'), ('--file', 'somefile.txt')] []
同样,我们也可以使用短选项,如下所示:
$ python3 main.py -m hello -f somefile.txt
# 输出 [('-m', 'hello'), ('-f', 'somefile.txt')] []
⚠️ 请注意,本例中的短选项 -m
不要与命令行标志 -m
混淆,命令行标志 -m
用于在运行 Python 脚本时将模块作为主模块运行。
例如,在运行 main.py
时,你会使用 python3 -m unittest main.py
将 unittest
作为主模块运行。
前面提到,所有其它的位置参数都会被收集到 args
变量中。 下面是一个例子:
$ python3 main.py -m hello -f somefile.txt another_argument
args
列表包含了位置参数 another_argument
。
# 输出 [('-m', 'hello'), ('-f', 'somefile.txt')] ['another_argument']
在这里,opts
是一个元组列表,我们可以遍历它,解包元组,并提取与特定选项对应的参数。
处理完这些参数后,我们应该如何处理文件名和消息呢? 我们可以以写入模式打开文件,并将转换为大写的消息字符串写入文件。
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=','file=']) print(opts) print(args) for option, argument in opts: if option == "-m": message = argument if option == '-f': file = argument with open(file,'w') as f: f.write(message.upper())
让我们使用短选项和命令行参数来运行 main.py
。
$ python main.py -m hello -f thisfile.txt [('-m', 'hello'), ('-f', 'thisfile.txt')] []
运行 main.py
后,我们可以在工作目录中看到名为 thisfile.txt
的文件。 该文件包含了被转换为大写的字符串 ‘hello’ (‘HELLO’)。
$ ls main.py thisfile.txt
$ cat thisfile.txt HELLO
如何使用 argparse
解析命令行参数
argparse
模块也是 Python 标准库的一部分,它提供了解析命令行参数和构建命令行接口的功能。
为了解析命令行参数,我们需要从 argparse
模块导入 ArgumentParser
类。 然后,我们实例化 arg_parser
,即一个 ArgumentParser
对象:
from argparse import ArgumentParser arg_parser = ArgumentParser()
接下来,我们要添加两个命令行参数:
message
:消息字符串;file
:我们想要使用的文件的名称。
现在,我们可以调用 arg_parser
的 add_argument()
方法来添加这两个参数。 在 add_argument()
方法调用中,你可以通过 help
字段设置参数的描述。
arg_parser.add_argument('message',help='消息字符串') arg_parser.add_argument('file',help='文件名')
到目前为止,我们已经实例化了 arg_parser
并添加了命令行参数。 当程序在命令行运行时,你可以使用 arg_parser
的 parse_args()
方法来获取参数的值。
在这里,我们将参数命名空间捕获到变量 args
中。 所以你可以通过 args.argument_name
来获取参数的值。
获取参数值后,我们将消息字符串(使用 swapcase()
字符串方法)进行大小写转换,并写入文件。
args = arg_parser.parse_args() message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
综合以上步骤,我们的 main.py
文件如下:
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('message',help='消息字符串') arg_parser.add_argument('file',help='文件名') args = arg_parser.parse_args() print(args) message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
了解命令行参数用法
为了解 main.py
的参数使用方法,你可以使用 --help
长选项,如下所示:
$ python3 main.py --help usage: main.py [-h] message file positional arguments: message 消息字符串 file 文件名 optional arguments: -h, --help 显示此帮助信息并退出
这里没有可选参数,message
和 file
都是必需的位置参数。 你也可以使用短选项 -h
:
$ python3 main.py -h usage: main.py [-h] message file positional arguments: message 消息字符串 file 文件名 optional arguments: -h, --help 显示此帮助信息并退出
如上所示,默认情况下这两个参数都是位置参数。 因此,如果你没有传递其中一个或多个参数,就会出错。
在以下示例中,我们为消息字符串传递了一个位置参数 (Hello),但没有为文件参数提供值。
结果,我们收到一个错误消息,提示需要文件参数。
$ python3 main.py Hello usage: main.py [-h] message file main.py: error: the following arguments are required: file
当使用两个位置参数运行 main.py
时,我们可以看到命名空间 args
中包含了参数的值。
$ python3 main.py Hello file1.txt
# 输出 Namespace(file="file1.txt", message="Hello")
现在,如果检查当前工作目录的内容,我们会看到脚本创建了一个文件 file1.txt
:
$ ls file1.txt main.py
原始的消息字符串是 ’Hello’; 在进行大小写转换后,file1.txt
文件中的消息字符串变为 “hELLO”。
$ cat file1.txt hELLO
如何使命令行参数可选
要使命令行参数可选,可以在参数名称前加上 --
。
现在,我们修改 main.py
,使消息和文件参数都是可选的。
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message',help='消息字符串') arg_parser.add_argument('--file',help='文件名')
由于命令行参数都是可选的,我们可以为这些参数设置默认值。
if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt"
此时,main.py
文件包含以下代码:
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message',help='消息字符串') arg_parser.add_argument('--file',help='文件名') args = arg_parser.parse_args() print(args) if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt" with open(file,'w') as f: f.write(message.swapcase())
如果检查用法,我们可以看到 message
和 file
都是可选参数。 这意味着你现在可以在没有这两个参数的情况下运行 main.py
。
$ python3 main.py --help usage: main.py [-h] [--message MESSAGE] [--file FILE] optional arguments: -h, --help 显示此帮助信息并退出 --message MESSAGE 消息字符串 --file FILE 文件名
$ python3 main.py
在参数命名空间中,file
和 message
都是 None
。
# 输出 Namespace(file=None, message=None)
我们看到程序使用了默认文件名和消息 myfile.txt
和 Python3
。 文件 myfile.txt
现在位于工作目录中:
$ ls file1.txt main.py myfile.txt
它包含了经过大小写转换后的字符串 Python3
:
$ cat myfile.txt pYTHON3
你也可以同时使用 --message
和 --file
参数来使命令更易读。
$ python3 main.py --message Coding --file file2.txt
# 输出 Namespace(file="file2.txt", message="Coding")
我们在工作目录中看到了 file2.txt
:
$ ls file1.txt file2.txt main.py myfile.txt
并且该文件包含了预期的字符串 ‘cODING’。
$ cat file2.txt cODING
结论
以下是对本文所学内容的总结:
- 与 C 语言类似,在 Python 中,你可以通过遍历参数向量
sys.argv
来访问命令行参数。sys.argv[0]
是 Python 脚本的名称。所以我们需要解析的参数是sys.argv[1:]
。 - 但是,为了提高代码的可读性并添加选项,可以使用
getopt
和argparse
模块。 - 你可以使用
getopt
模块来解析从索引 1 到列表末尾的命令行参数列表。 你可以定义短选项和长选项。 - 当选项需要参数时,你可以在短选项后添加冒号 (:),在长选项后添加等号 (=)。
- 使用 Python 的
argparse
模块,你可以实例化一个ArgumentParser
对象,并使用add_argument()
方法添加所需的位置参数。在参数名称前加上--
可以使其成为可选参数。 - 要检索命令行参数的值,请在
ArgumentParser
对象上调用parse_args()
方法。
接下来,学习如何在 Python 中执行安全哈希。