Python中的argparse模块

发布于:2024-05-07 ⋅ 阅读:(17) ⋅ 点赞:(0)

1. 简介

argparse 是 Python 标准库中用于处理命令行参数的模块。它提供了一种简单而灵活的方法来编写命令行界面,并可以自动生成帮助和用法信息。使用 argparse,您可以定义程序接受的命令行参数的类型、数量和格式,并让 Python 解析和验证这些参数。

以下是 argparse 的一些主要特点和用法:

  1. 定义参数:您可以使用 argparse 定义程序期望的参数。这些参数可以是位置参数(必须提供且顺序固定)或可选参数(可以选择性地提供)。
  2. 自动生成帮助信息argparse 可以根据您定义的参数自动生成帮助信息。这使得用户可以使用 --help 参数来获取关于程序如何使用的详细信息。
  3. 类型检查和转换:您可以指定参数的类型,并让 argparse 自动检查和转换用户提供的值,以确保它们具有正确的类型。
  4. 默认值:您可以为参数指定默认值,如果用户未提供该参数,则使用默认值。
  5. 互斥参数:您可以定义一组参数中只能提供一个的互斥参数。
  6. 子命令argparse 支持定义子命令,使您可以构建具有多个子命令的命令行工具。
  7. 自定义操作:您可以定义参数的操作,例如存储值、调用函数等。
  8. 多种风格的使用argparse 提供了多种不同风格的 API,以适应不同的使用场景和个人偏好。

argparse 是一个功能强大且易于使用的工具,适用于编写各种类型的命令行工具,从简单的脚本到复杂的应用程序都可以使用。

2. 使用示例1:简单的计算器

下面是一个简单的例子,演示如何使用 argparse 模块创建一个命令行工具,该工具接受两个整数作为输入,并计算它们的和:

import argparse

def add_numbers(num1, num2):
    """计算两个整数的和"""
    return num1 + num2

def main():
    # 创建 ArgumentParser 对象,用于解析命令行参数
    parser = argparse.ArgumentParser(description='Add two integers')

    # 添加位置参数,这里我们要求用户提供两个整数
    parser.add_argument('num1', type=int, help='first integer')
    parser.add_argument('num2', type=int, help='second integer')

    # 解析命令行参数
    args = parser.parse_args()

    # 调用 add_numbers 函数计算两个整数的和
    result = add_numbers(args.num1, args.num2)

    # 输出结果
    print(f'The sum of {args.num1} and {args.num2} is {result}')

if __name__ == '__main__':
    main()

在这个例子中:

  • import argparse:导入 argparse 模块。
  • def add_numbers(num1, num2)::定义了一个函数 add_numbers,用于计算两个整数的和。
  • def main()::定义了主函数。
  • parser = argparse.ArgumentParser(description='Add two integers'):创建了一个 ArgumentParser 对象,并指定了工具的描述信息。
  • parser.add_argument('num1', type=int, help='first integer')parser.add_argument('num2', type=int, help='second integer'):分别添加了两个位置参数 num1num2,并指定了它们的类型为整数。
  • args = parser.parse_args():解析命令行参数,并将结果存储在 args 中。
  • result = add_numbers(args.num1, args.num2):调用 add_numbers 函数,将用户提供的整数作为参数传递给它,并得到计算结果。
  • print(f'The sum of {args.num1} and {args.num2} is {result}'):输出计算结果。

保存上述文件名为example.py, 然后在终端,用户可以通过命令行运行该脚本,并提供两个整数作为参数,程序将计算这两个整数的和并输出结果。例如:

python example.py 10 20   # 这里example.py就是你的脚本文件名字
The sum of 10 and 20 is 30

注意:在进行上述命令前,先将工作目录cd到当前程序所在的文件夹。 例如:cd arg_files

如果用户在命令行上使用 --help 参数,将会显示程序的帮助信息:

python example.py --help
usage: example.py [-h] num1 num2

Add two integers

positional arguments:
  num1        first integer
  num2        second integer

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

3. 定义参数

argparse 中,您可以使用 add_argument() 方法来定义参数。例如下面的例子,演示了如何使用 argparse 定义不同类型的参数:

import argparse

def main():
    # 创建 ArgumentParser 对象
    parser = argparse.ArgumentParser(description='ArgumentParser Example')

    # 添加位置参数
    parser.add_argument('input_file', type=str, help='Input file path')

    # 添加可选参数(标记参数)
    parser.add_argument('-o', '--output_file', type=str, default='output.txt', help='Output file path')

    # 添加可选参数(带参数值)
    parser.add_argument('-l', '--limit', type=int, default=100, help='Limit the number of lines to read')

    # 添加互斥参数
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--verbose', action='store_true', help='Print verbose output')
    group.add_argument('--quiet', action='store_true', help='Suppress all output')

    # 解析命令行参数
    args = parser.parse_args()

    # 输出解析结果
    print(f'Input file: {args.input_file}')
    print(f'Output file: {args.output_file}')
    print(f'Limit: {args.limit}')
    if args.verbose:
        print('Verbose mode enabled')
    elif args.quiet:
        print('Quiet mode enabled')

if __name__ == '__main__':
    main()

在上面例子中:

  • parser.add_argument('input_file', type=str, help='Input file path'):添加了一个位置参数,该参数接受一个字符串类型的值,用于指定输入文件的路径。用户必须提供这个参数。
  • parser.add_argument('-o', '--output_file', type=str, default='output.txt', help='Output file path'):添加了一个可选参数,用户可以选择性地提供该参数。参数名可以是 -o--output_file,它接受一个字符串类型的值,默认值为 'output.txt',用于指定输出文件的路径。
  • parser.add_argument('-l', '--limit', type=int, default=100, help='Limit the number of lines to read'):同样添加了一个可选参数,用于限制读取的行数。参数名可以是 -l--limit,它接受一个整数类型的值,默认值为 100
  • group = parser.add_mutually_exclusive_group():创建了一个互斥参数组。
  • group.add_argument('--verbose', action='store_true', help='Print verbose output')group.add_argument('--quiet', action='store_true', help='Suppress all output'):在互斥参数组中分别添加了两个互斥的参数,用户只能选择其中一个。--verbose 参数用于启用详细输出,而 --quiet 参数用于禁止所有输出。
  • args = parser.parse_args():解析命令行参数。
  • 输出解析结果:根据解析的参数输出相应的信息。

保存上面代码为example1.py,可以尝试在终端提供不同的命令行参数来查看程序的行为。

python example1.py input.txt

输出为:

Input file: input.txt
Output file: output.txt
Limit: 100

这里仅提供了必需的位置参数 input_file,输出文件和限制行数将采用默认值。

我们也可以提供所有参数

python example1.py input.txt -o output.txt -l 50 --verbose

输出为:

Input file: input.txt
Output file: output.txt
Limit: 50
Verbose mode enabled

这里我们提供了所有参数,输入文件为 input.txt,输出文件为 output.txt,限制行数为 50,并启用了详细输出。

使用互斥参数

python example1.py input.txt --quiet

输出为:

Input file: input.txt
Output file: output.txt
Limit: 100
Quiet mode enabled

4. 使用示例2:简单的文件操作工具

首先我们建立一个txt文件,并保存在当前工作路径文件夹下,这里我们存储如下文本

All that we are is the result of what we have thought.

If you judge people, you have no time to love them.

The greatest wealth is to live content with little.

保存文件名为test.txt。

建立如下代码工具

import argparse

def count_lines(filename):
    """计算文件中的行数"""
    with open(filename, 'r') as file:
        lines = file.readlines()
        return len(lines)

def main():
    # 创建 ArgumentParser 对象
    parser = argparse.ArgumentParser(description='简单的文件操作工具')

    # 添加位置参数
    parser.add_argument('filename', type=str, help='要处理的文件名')

    # 解析命令行参数
    args = parser.parse_args()

    # 调用 count_lines 函数计算文件中的行数
    line_count = count_lines(args.filename)

    # 输出结果
    print(f'{args.filename} 中的行数为: {line_count}')

if __name__ == '__main__':
    main()

这个工具将读取一个文本文件,并计算其中的行数, 保存文件名为example3.py。然后在终端运行

python example3.py test.txt
test.txt 中的行数为: 5

5. 类型检查和转换

argparse 中,您可以指定参数的类型,并让它自动检查和转换用户提供的值,以确保它们具有正确的类型。

import argparse

def main():
    # 创建 ArgumentParser 对象
    parser = argparse.ArgumentParser(description='类型检查和转换示例')

    # 添加参数,并指定类型
    parser.add_argument('integer', type=int, help='整数参数')
    parser.add_argument('float_number', type=float, help='浮点数参数')

    # 解析命令行参数
    args = parser.parse_args()

    # 输出结果
    print(f'整数参数:{args.integer}')
    print(f'浮点数参数:{args.float_number}')

if __name__ == '__main__':
    main()

保存文件名为example4.py,然后在终端运行

python example4.py 10 3.14
整数参数:10
浮点数参数:3.14

在这个示例中,我们使用 type=inttype=float 分别指定了 integerfloat_number 参数的类型为整数和浮点数。当用户提供参数时,argparse 会自动将字符串转换为相应的类型,并在解析时进行类型检查。

如果用户提供的参数无法转换为指定的类型,argparse 将会报错并显示帮助信息。例如,如果用户提供的参数不是有效的整数或浮点数,将会得到类似以下的错误信息:

python example4.py abc 3.14
usage: example4.py [-h] integer float_number
script.py: error: argument integer: invalid int value: 'abc'

6. 自定义操作

argparse 中,您可以使用 action 参数来定义参数的操作,例如存储值、调用函数等。这允许您在解析参数时执行自定义的操作。例如

import argparse

# 自定义操作函数
def custom_action(value):
    print(f'执行自定义操作,参数值为:{value}')

def main():
    # 创建 ArgumentParser 对象
    parser = argparse.ArgumentParser(description='自定义操作示例')

    # 添加参数,并指定自定义操作函数
    parser.add_argument('value', type=str, help='自定义操作参数', action='store', nargs='?', const='default')
    parser.add_argument('--custom', action='store_const', const='custom_value', help='执行自定义操作')

    # 解析命令行参数
    args = parser.parse_args()

    # 如果提供了自定义操作参数,则执行自定义操作函数
    if args.value:
        custom_action(args.value)
    # 如果提供了 --custom 参数,则输出相应信息
    elif args.custom:
        print('执行自定义操作:custom_value')
    else:
        print('未提供参数')

if __name__ == '__main__':
    main()

保存上述文件名为example5.py,然后在终端运行

python example5.py
未提供参数

python example5.py --custom
执行自定义操作:custom_value

python example5.py custom_argument
执行自定义操作,参数值为:custom_argument

在这个示例中,我们定义了一个自定义操作函数 custom_action,该函数接受一个参数,并在执行时打印该参数的值。

然后,我们定义了两个参数:value--custom。对于 value 参数,我们将其 action 设置为 'store',这意味着它将会存储值,并调用我们定义的自定义操作函数。对于 --custom 参数,我们将其 action 设置为 'store_const',这意味着它将存储一个常量值,并在解析时执行我们指定的操作。

7. 进阶功能:子命令

当您熟悉了 argparse 的基本用法后,可以尝试使用其进阶功能来构建更复杂和灵活的命令行工具。有时候,您可能希望为命令行工具添加子命令,每个子命令都有自己的参数。argparse 允许您使用 add_subparsers() 方法来实现这一功能。例如

import argparse

def main():
    # 创建 ArgumentParser 对象
    parser = argparse.ArgumentParser(description='子命令示例')

    # 创建子命令解析器
    subparsers = parser.add_subparsers(title='子命令', dest='command')

    # 添加子命令:say
    say_parser = subparsers.add_parser('say', help='输出一段文字')
    say_parser.add_argument('message', type=str, help='要输出的文字')

    # 添加子命令:add
    add_parser = subparsers.add_parser('add', help='计算两个数字的和')
    add_parser.add_argument('num1', type=int, help='第一个数字')
    add_parser.add_argument('num2', type=int, help='第二个数字')

    # 解析命令行参数
    args = parser.parse_args()

    # 根据子命令执行相应的操作
    if args.command == 'say':
        print(args.message)
    elif args.command == 'add':
        result = args.num1 + args.num2
        print(f'和为:{result}')

if __name__ == '__main__':
    main()

保存上面代码为example6.py。然后在终端运行

python example6.py say "Hello, world!"
Hello, world!

python example6.py add 5 7
和为:12

8.多种风格的使用

在使用 argparse 时,可以根据个人喜好和项目需求选择不同的风格。下面是一些常见的使用风格示例:

面向对象风格

import argparse

class MyCLI:
    def __init__(self):
        self.parser = argparse.ArgumentParser(description='My CLI')

        self.parser.add_argument('name', type=str, help='Your name')
        self.parser.add_argument('--age', type=int, help='Your age', default=18)

    def run(self):
        args = self.parser.parse_args()
        print(f'Hello, {args.name}! You are {args.age} years old.')

if __name__ == '__main__':
    cli = MyCLI()
    cli.run()

函数式风格

import argparse

def parse_args():
    parser = argparse.ArgumentParser(description='My CLI')

    parser.add_argument('name', type=str, help='Your name')
    parser.add_argument('--age', type=int, help='Your age', default=18)

    return parser.parse_args()

def main():
    args = parse_args()
    print(f'Hello, {args.name}! You are {args.age} years old.')

if __name__ == '__main__':
    main()

模块级别风格

import argparse

parser = argparse.ArgumentParser(description='My CLI')

parser.add_argument('name', type=str, help='Your name')
parser.add_argument('--age', type=int, help='Your age', default=18)

args = parser.parse_args()

print(f'Hello, {args.name}! You are {args.age} years old.')