# Python `argparse`教程

> 原文： [http://zetcode.com/python/argparse/](http://zetcode.com/python/argparse/)

Python `argparse`教程展示了如何使用`argparse`模块解析 Python 中的命令行参数。

## Python 的`argparse`

通过`argparse`模块，可以轻松编写用户友好的命令行界面。 它解析`sys.argv`中定义的参数。

`argparse`模块还会自动生成帮助和使用消息，并在用户为程序提供无效参数时发出错误。

`argparse`是标准模块； 我们不需要安装它。

使用`ArgumentParser`创建一个解析器，并使用`add_argument()`添加一个新参数。 参数可以是可选的，必需的或定位的。

## Python `argparse`可选参数

下面的示例创建一个简单的参数解析器。

`optional_arg.py`

```py
#!/usr/bin/env 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`。 这些是可选参数。

```py
import argparse

```

该模块已导入。

```py
parser.add_argument('-o', '--output', action='store_true', 
    help="shows output")

```

参数添加了`add_argument()`。 如果设置为`store_true`，则`action`会将参数存储为`True`。 help 选项提供参数帮助。

```py
args = parser.parse_args()

```

参数由`parse_args()`解析。 解析的参数作为对象属性存在。 在我们的例子中，将有`args.output`属性。

```py
if args.output:
    print("This is some output")

```

如果存在该参数，我们将显示一些输出。

```py
$ optional_arg.py -o
This is some output
$ optional_arg.py --output
This is some output

```

我们使用`-o`和`--output`运行程序。

```py
$ optional_arg.py --help
usage: optional_arg.py [-h] [-o]

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

```

我们可以向程序显示帮助。

## Python `argparse`必需参数

使用`required`选项需要一个参数。

`required_arg.py`

```py
#!/usr/bin/env python

import argparse

# required arg

parser = argparse.ArgumentParser()

parser.add_argument('--name', required=True)

args = parser.parse_args()

print(f'Hello {args.name}')

```

该示例必须指定`name`选项； 否则失败。

```py
$ 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

```

这是输出。

## Python `argparse`位置参数

以下示例适用于位置参数。 它们是使用`add_argument()`创建的。

`positional_arg.py`

```py
#!/usr/bin/env 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。

```py
parser.add_argument('name')
parser.add_argument('age')

```

创建位置参数时不带破折号前缀字符。

```py
$ positional_arg.py Peter 23
Peter is 23 years old

```

这是示例输出。

## Python `argparse`目标

`add_argument()`的`dest`选项为参数指定名称。 如果未给出，则从选项中推断出来。

`dest.py`

```py
#!/usr/bin/env 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}")

```

程序将`now`名称赋予`-n`参数。

```py
$ dest.py -n
Now: 2019-03-22 17:37:40.406571

```

这是输出。

## Python `argparse`类型

`type`参数确定参数类型。

`rand_int.py`

```py
#!/usr/bin/env 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 个随机整数。

```py
parser.add_argument('-n', type=int, required=True, 
    help="define the number of random integers")

```

`-n`选项需要整数值，这是必需的。

```py
$ rand_int.py -n 3
92
-61
-61

```

这是一个示例输出。

## Python `argparse`默认

如果未指定`default`选项，则指定默认值。

`power.py`

```py
#!/usr/bin/env 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。

```py
$ power.py -b 3
9
$ power.py -b 3 -e 3
27

```

这是输出。

## Python argparse metavar

`metavar`选项为错误的期望值命名，并提供帮助输出。

`metavar.py`

```py
#!/usr/bin/env 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`。

```py
$ 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

```

给定的名称显示在帮助输出中。

## Python `argparse`追加操作

`append`操作允许对重复选项进行分组。

`appending.py`

```py
#!/usr/bin/env 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`选项指定所有名称。 它们可以重复多次重复。

```py
$ appending.py -n Peter -n Lucy --name Jane
Hello Peter!
Hello Lucy!
Hello Jane!

```

这是输出。

## Python 的`argparse nargs`

`nargs`指定应使用的命令行参数的数量。

`charseq.py`

```py
#!/usr/bin/env 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)

```

该示例显示了从字符一到字符二的字符序列。 它需要两个参数。

```py
parser.add_argument('chars', type=str, nargs=2, metavar='c',
    help='starting and ending character')

```

使用`nargs=2`，我们指定期望两个参数。

```py
$ charseq.py e k
e f g h i j k

```

程序显示从`e`到`k`的字符序列。

可以使用`*`字符设置可变数量的参数。

`var_args.py`

```py
#!/usr/bin/env 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)}")

```

该示例计算值的总和。 我们可以为程序指定可变数量的参数。

```py
$ var_args.py 1 2 3 4 5
The sum of values is 15

```

这是输出。

## Python `argparse`选择

`choices`选项将参数限制为给定列表。

`mytime.py`

```py
#!/usr/bin/env 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`。

```py
$ mytime.py --now iso
2019-03-27T11:34:54.106643

$ mytime.py --now unix
1553682898.422863

```

这是一个示例输出。

## 头例子

以下示例模仿 Linux `head`命令。 它显示了文件开头的 n 行文本。

`words.txt`

```py
sky
top
forest
wood
lake
wood

```

对于示例，我们有这个小的测试文件。

`head.py`

```py
#!/usr/bin/env 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`表示要显示的行数。

```py
$ head.py words.txt 3
sky
top
forest

```

这是输出。

这是 Python `argparse`教程。 您可能也对 [Python `pathlib`教程](/python/pathlib/)和 [Python 教程](/lang/python/)感兴趣。