如何在 Python 中解析命令行参数

想要使用命令行参数运行 Python 脚本? 了解如何在 Python 中使用 sys、getopt 和 argparse 模块解析命令行参数。

在 Python 中,当您想要读取用户输入时,您将使用 input() 函数。 但是,对于某些应用程序,您可能希望在命令行运行脚本时传入某些参数。

在本教程中,我们将学习如何在命令行中使用选项和参数运行 Python 脚本。 然后我们将学习如何使用 Python 的内置模块来解析这些选项和参数。

让我们开始!

理解 Python 中的 sys.argv

如果您使用 C 语言编程,您就会知道向程序传递参数的最简单方法之一是通过命令行。 为此,您可以像这样构建主要功能:

#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 循环和枚举函数遍历参数向量:

# main.py

import sys

for idx, arg in enumerate(sys.argv):
    print(f"arg{idx}: {arg}")
# Output
arg0:main.py
arg1:hello
arg2:world
arg3:python
arg4:script

我们看到第一个参数(在索引 0 处)是 Python 文件的名称。 后续参数从索引 1 开始。

这是一个接受和处理命令行参数的最小工作程序。 但是,我们看到了一些问题:

  • 程序的用户如何知道要传入哪些参数?
  • 这些论点代表什么?

这个不是很清楚。 要解决此问题,您可以使用 getopt 或 argparse 模块。 我们将在下一节中学习。✅

使用 Python 的 getopt 解析命令行参数

让我们学习如何使用内置的 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 是一个空列表。

# Output
[("--message', 'hello'), ('--file', 'somefile.txt')]
[]

同样,我们也可以使用short选项,如下所示:

$ python3 main.py -m hello -f somefile.txt
# Output
[('-m', 'hello'), ('-f', 'somefile.txt')]
[]

⚠️ 本例中的 -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。

# Output
[('-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()

接下来,我们要添加两个命令行参数:

  • 消息:消息字符串,和
  • 文件:我们要使用的文件的名称。
  如何不在微信中分享朋友圈

现在我们调用 arg_parser 上的 add_argument() 方法来添加这两个参数。 在 add_argument() 方法调用中,您可以将帮助设置为字符串(参数的描述)。

arg_parser.add_argument('message',help='message string')
arg_parser.add_argument('file',help='filename')

到目前为止,我们已经实例化了 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='message string')
arg_parser.add_argument('file',help='filename')

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 long 选项,如下所示:

$ python3 main.py --help
usage: main.py [-h] message file

positional arguments:
  message     message string
  file        filename

optional arguments:
  -h, --help  show this help message and exit

没有可选参数,消息和文件都是必需的位置参数。 或者,您也可以使用短选项 -h:

$ python3 main.py -h
usage: main.py [-h] message file

positional arguments:
  message     message string
  file        filename

optional arguments:
  -h, --help  show this help message and exit

如图所示,默认情况下这两个参数都是位置参数。 因此,如果您不传递这些参数中的一个或多个,就会出错。

在这里,我们为消息字符串传入了一个位置参数 (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
# Output
Namespace(file="file1.txt", message="Hello")

现在,如果我们检查当前工作目录的内容,我们会看到脚本创建了文件“file1.txt”:

$ ls
file1.txt  main.py

原始消息字符串为’Hello’; 交换大小写后,文件“file1.txt”中的消息字符串为“hELLO”。

$ cat file1.txt
hELLO

如何使命令行参数可选

要使这些命令行参数可选,您可以在参数名称前加上 –。

  11 个 Illustrator 插件可最大限度地发挥您的设计潜力

让我们修改 main.py 使消息和文件参数都是可选的。

# main.py

from argparse import ArgumentParser

arg_parser = ArgumentParser()
arg_parser.add_argument('--message',help='message string')
arg_parser.add_argument('--file',help='filename')

由于命令行参数都是可选的,我们可以为这些参数设置默认值。

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='message string')
arg_parser.add_argument('--file',help='filename')

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         show this help message and exit
  --message MESSAGE  message string
  --file FILE        filename
$ python3 main.py

在参数命名空间中,file 和 message 都是 None。

# Output
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
# Output
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 来访问命令行参数。 系统参数[0] 是 Python 脚本的名称。 所以我们有兴趣解析参数 sys.argv[1:].
  • 但是,为了增强可读性和能够添加选项,您可以使用 getopt 和 argparse 模块。
  • 您可以使用 getopt 模块来解析从索引 1 开始到列表末尾的命令行参数列表。 您可以同时指定短选项和长选项。
  • When an option takes an argument, you can specify a colon (:) and = after the short option and long option, respectively.
  • 使用 Python 的 argparse 模块,您可以实例化一个 ArgumentParser 对象并使用 add_argument() 方法添加所需的位置参数。 在参数名称之前使用 — 使其成为可选的。
  • 要检索命令行参数的值,请对 ArgumentParser 对象调用 parse_args() 方法。

接下来,学习如何在 Python 中执行安全散列。