Python argparse
最后修改于 2024 年 9 月 24 日
在本文中,我们将展示如何使用 argparse 模块解析 Python 中的命令行参数。
Python argparse
argparse 模块可以轻松编写用户友好的命令行界面。它从 sys.argv 解析定义的参数。
argparse 模块还会自动生成帮助和用法消息,并在用户向程序提供无效参数时发出错误。
argparse 是一个标准模块;我们无需安装它。
使用 ArgumentParser 创建解析器,并使用 add_argument 添加新参数。参数可以是可选的、必需的或位置参数。
可选参数
以下示例创建了一个简单的参数解析器。
#!/usr/bin/python
import argparse
# help flag provides flag help
# store_true actions stores argument as True
parser = argparse.ArgumentParser()
parser.add_argument('-o', '--output', action='store_true',
help="shows output")
args = parser.parse_args()
if args.output:
print("This is some output")
该示例添加了一个具有两个选项的参数:一个短选项 -o 和一个长选项 --ouput。这些是可选参数。
import argparse
导入模块。
parser.add_argument('-o', '--output', action='store_true',
help="shows output")
使用 add_argument 添加一个参数。将 action 设置为 store_true 将在参数存在时将其存储为 True。help 选项提供参数帮助。
args = parser.parse_args()
使用 parse_args 解析参数。解析后的参数作为对象属性存在。在我们的例子中,将有一个 args.output 属性。
if args.output:
print("This is some output")
如果参数存在,我们将显示一些输出。
$ optional_arg.py -o This is some output $ optional_arg.py --output This is some output
我们使用 -o 和 --output 运行程序。
$ optional_arg.py --help
usage: optional_arg.py [-h] [-o]
optional arguments:
-h, --help show this help message and exit
-o, --output shows output
我们可以显示程序帮助。
必需参数
使用 required 选项将参数设置为必需参数。
#!/usr/bin/python
import argparse
# required arg
parser = argparse.ArgumentParser()
parser.add_argument('--name', required=True)
args = parser.parse_args()
print(f'Hello {args.name}')
该示例必须指定 name 选项;否则会失败。
$ required_arg.py --name Peter Hello Peter $ required_arg.py usage: required_arg.py [-h] --name NAME required_arg.py: error: the following arguments are required: --name
位置参数
以下示例使用位置参数。它们是使用 add_argument 创建的。
#!/usr/bin/python
import argparse
# positional args
parser = argparse.ArgumentParser()
parser.add_argument('name')
parser.add_argument('age')
args = parser.parse_args()
print(f'{args.name} is {args.age} years old')
该示例需要两个位置参数:name 和 age。
parser.add_argument('name')
parser.add_argument('age')
位置参数的创建不带连字符前缀。
$ positional_arg.py Peter 23 Peter is 23 years old
dest 选项
add_argument 的 dest 选项为参数指定一个名称。如果未给出,则从选项中推断。
#!/usr/bin/python
import argparse
import datetime
# dest gives a different name to a flag
parser = argparse.ArgumentParser()
parser.add_argument('-n', dest='now', action='store_true', help="shows now")
args = parser.parse_args()
# we can refer to the flag
# by a new name
if args.now:
now = datetime.datetime.now()
print(f"Now: {now}")
该程序为 -n 参数赋予了 now 名称。
$ ./dest.py -n Now: 2022-08-20 09:42:32.195881
type 参数
type 参数确定参数的类型。
#!/usr/bin/python
import argparse
import random
# type determines the type of the argument
parser = argparse.ArgumentParser()
parser.add_argument('-n', type=int, required=True,
help="define the number of random integers")
args = parser.parse_args()
n = args.n
for i in range(n):
print(random.randint(-100, 100))
该程序显示 -100 到 100 之间的 n 个随机整数。
parser.add_argument('-n', type=int, required=True,
help="define the number of random integers")
-n 选项需要一个整数值,并且是必需的。
$ rand_int.py -n 3 92 -61 -61
default 选项
default 选项指定默认值,如果未给出该值。
#!/usr/bin/python
import argparse
# required defines a mandatory argument
# default defines a default value if not specified
parser = argparse.ArgumentParser()
parser.add_argument('-b', type=int, required=True, help="defines the base value")
parser.add_argument('-e', type=int, default=2, help="defines the exponent value")
args = parser.parse_args()
val = 1
base = args.b
exp = args.e
for i in range(exp):
val *= base
print(val)
该示例计算指数。指数值不是必需的;如果未给出,则默认为 2。
$ power.py -b 3 9 $ power.py -b 3 -e 3 27
metavar 选项
metavar 选项为错误和帮助输出中预期的值指定一个名称。
#!/usr/bin/python
import argparse
# metavar gives name to the expected value
# in error and help outputs
parser = argparse.ArgumentParser()
parser.add_argument('-v', type=int, required=True, metavar='value',
help="computes cube for the given value")
args = parser.parse_args()
print(args)
val = args.v
print(val * val * val)
该示例将预期值命名为 value。默认名称是 V。
$ metavar.py -h usage: metavar.py [-h] -v value optional arguments: -h, --help show this help message and exit -v value computes cube for the given value
给定的名称显示在帮助输出中。
append 操作
append 操作允许对重复的选项进行分组。
#!/usr/bin/python
import argparse
# append action allows to group repeating
# options
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--name', dest='names', action='append',
help="provides names to greet")
args = parser.parse_args()
names = args.names
for name in names:
print(f'Hello {name}!')
该示例向使用 n 或 name 选项指定的所有名称生成问候消息;它们可以重复多次。
$ appending.py -n Peter -n Lucy --name Jane Hello Peter! Hello Lucy! Hello Jane!
nargs 选项
nargs 指定应消耗的命令行参数的数量。
#!/usr/bin/python
import argparse
import sys
# nargs sets the required number of argument values
# metavar gives name to argument values in error and help output
parser = argparse.ArgumentParser()
parser.add_argument('chars', type=str, nargs=2, metavar='c',
help='starting and ending character')
args = parser.parse_args()
try:
v1 = ord(args.chars[0])
v2 = ord(args.chars[1])
except TypeError as e:
print('Error: arguments must be characters')
parser.print_help()
sys.exit(1)
if v1 > v2:
print('first letter must precede the second in alphabet')
parser.print_help()
sys.exit(1)
该示例显示从字符一到字符二的字符序列。它需要两个参数。
parser.add_argument('chars', type=str, nargs=2, metavar='c',
help='starting and ending character')
使用 nargs=2,我们指定我们期望两个参数。
$ charseq.py e k e f g h i j k
该程序显示从 e 到 k 的字符序列。
可以使用 * 字符设置可变数量的参数。
#!/usr/bin/python
import argparse
# * nargs expects 0 or more arguments
parser = argparse.ArgumentParser()
parser.add_argument('num', type=int, nargs='*')
args = parser.parse_args()
print(f"The sum of values is {sum(args.num)}")
该示例计算值的总和;我们可以为程序指定可变数量的参数。
$ var_args.py 1 2 3 4 5 The sum of values is 15
choices 选项
choices 选项将参数限制在给定的列表中。
#!/usr/bin/python
import argparse
import datetime
import time
# choices limits argument values to the
# given list
parser = argparse.ArgumentParser()
parser.add_argument('--now', dest='format', choices=['std', 'iso', 'unix', 'tz'],
help="shows datetime in given format")
args = parser.parse_args()
fmt = args.format
if fmt == 'std':
print(datetime.date.today())
elif fmt == 'iso':
print(datetime.datetime.now().isoformat())
elif fmt == 'unix':
print(time.time())
elif fmt == 'tz':
print(datetime.datetime.now(datetime.timezone.utc))
在示例中,now 选项可以接受以下值:std、iso、unix 或 tz。
$ ./mytime.py --now iso 2022-08-20T09:44:22.437880 $ ./mytime.py --now unix 1660981466.8261166
head 示例
以下示例模仿 Linux head 命令。它显示文件开头 n 行的文本。
sky top forest wood lake wood
对于示例,我们有这个小测试文件。
#!/usr/bin/python
import argparse
from pathlib import Path
# head command
# working with positional arguments
parser = argparse.ArgumentParser()
parser.add_argument('f', type=str, help='file name')
parser.add_argument('n', type=int, help='show n lines from the top')
args = parser.parse_args()
filename = args.f
lines = Path(filename).read_text().splitlines()
for line in lines[:args.n]:
print(line)
该示例有两个选项:f 用于文件名,-n 用于要显示的行数。
$ head.py words.txt 3 sky top forest
互斥选项
add_mutually_exclusive_group 创建一个互斥选项组。
以下程序列出正在运行的进程。它使用 psutil 库来列出进程,并使用 rich 库将数据以表格形式输出。
import psutil
import argparse
from datetime import datetime
from rich import box
from rich.console import Console
from rich.table import Table
from datetime import date
def parse_arguments():
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-a', '--all', action='store_true',
help='show all processes')
group.add_argument('-n', '--name', help='show info about process name')
args = parser.parse_args()
return args.all, args.name
def list_process(name):
now = f'{date.today()}'
table = Table(title=f'Process', box=box.MINIMAL,
caption=now, caption_justify='left')
table.add_column('id', style='cyan')
table.add_column('process name', style='grey69')
table.add_column('username')
table.add_column('create time', style='blue')
table.add_column('memory', style='green')
process_count = 0
for p in psutil.process_iter():
if name in p.name().lower():
ctime = datetime.fromtimestamp(p.create_time())
memory_percent = p.memory_percent()
table.add_row(f'{p.pid}', p.name(), p.username(),
ctime.isoformat(), f'{memory_percent:.2f}')
process_count += 1
if process_count > 0:
console = Console()
console.print(table, justify='center')
else:
print('no such process found')
def list_all_processes():
now = f'{date.today()}'
table = Table(title='Processes', box=box.MINIMAL,
caption=now, caption_justify='left')
table.add_column('id', style='cyan')
table.add_column('process name', style='grey69')
pnames = []
for p in psutil.process_iter():
pnames.append(p.name())
table.add_row(f'[bold]{p.pid}', f'[bold]{p.name()}')
console = Console()
console.print(table, justify='center')
print(len(pnames), 'processes')
print(len(set(pnames)), 'apps')
all_f, name = parse_arguments()
if all_f:
list_all_processes()
elif name:
list_process(name)
该程序提供有关正在运行的进程的信息。根据提供的选项,它要么列出所有正在运行的进程,要么提供有关特定进程的更多信息。
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-a', '--all', action='store_true',
help='show all processes')
group.add_argument('-n', '--name', help='show info about process name')
-a 和 -n 选项是互斥的;我们要么列出所有进程,要么只列出特定进程。
来源
在本文中,我们学习了 Python argparse 模块。
作者
列出所有 Python 教程。