python散装笔记——83: 解析命令行参数

python散装笔记——83: 解析命令行参数大多数命令行工具依赖于程序执行时传递给程序的参数 这些程序不提示输入 而是期望设置数据或特定的标志 变成布尔值 这使得用户和其他程序都能在 Python 文件启动时通过数据运行它 本节将解释和演示 Python 命令行参数的实现和使用

大家好,欢迎来到IT知识分享网。

大多数命令行工具依赖于程序执行时传递给程序的参数。这些程序不提示输入,而是期望设置数据或特定的标志(变成布尔值)。这使得用户和其他程序都能在 Python 文件启动时通过数据运行它。本节将解释和演示 Python 命令行参数的实现和使用。

1: argparse 中的 Hello world

下面的程序会向用户问好。它需要一个位置参数,即用户名,也可以告诉用户问候语。

import argparse parser = argparse.ArgumentParser() parser.add_argument('name', help='name of user') parser.add_argument('-g', '--greeting', default='Hello', help='optional alternate greeting' ) args = parser.parse_args() print("{greeting}, {name}!".format( greeting=args.greeting, name=args.name) ) $ python hello.py --help usage: hello.py [-h] [-g GREETING] name positional arguments: name name of user optional arguments: -h, --help show this help message and exit -g GREETING, --greeting GREETING optional alternate greeting $ python hello.py world Hello, world! $ python hello.py John -g Howdy Howdy, John!
python散装笔记——83: 解析命令行参数

详情请阅读 argparse 文档。

2: 使用 argv 命令行参数

每当从命令行调用 Python 脚本时,用户可以提供额外的命令行参数,这些参数将传递给脚本。程序员可以通过系统变量 sys.argv 获取这些参数(argv 是大多数编程语言的传统名称,意思是 “参数向量”)。

按照惯例,sys.argv 列表中的第一个元素是 Python 脚本本身的名称,而其余元素则是用户在调用脚本时传递的标记。

# cli.py import sys print(sys.argv) $ python3 cli.py => ['cli.py'] $ python3 cli.py fizz => ['cli.py', 'fizz'] $ python3 cli.py fizz buzz => ['cli.py', 'fizz', 'buzz']
python散装笔记——83: 解析命令行参数

下面是另一个如何使用 argv 的例子。我们首先去掉 sys.argv 的初始元素,因为它包含脚本的名称。然后,我们将其余参数合并成一句话,最后打印这句话,并在前面加上当前登录用户的名称(以便模拟聊天程序)。

import getpass import sys words = sys.argv[1:] sentence = " ".join(words) print("[%s] %s" % (getpass.getuser(), sentence))

在 “手动 ”解析大量非位置参数时,通常使用的算法是遍历 sys.argv 列表。一种方法是遍历该列表并弹出其中的每个元素:

# reverse and copy sys.argv argv = reversed(sys.argv) # extract the first element arg = argv.pop() # stop iterating when there's no more args to pop() while len(argv) > 0: if arg in ('-f', '--foo'): print('seen foo!') elif arg in ('-b', '--bar'): print('seen bar!') elif arg in ('-a', '--with-arg'): arg = arg.pop() print('seen value: {}'.format(arg)) # get the next value arg = argv.pop()

3: 使用 argparse 设置互斥参数

如果希望两个或多个参数互斥。可以使用函数
argparse.ArgumentParser.add_mutually_exclusive_group()
。在下面的示例中,foo 或 bar 可以存在,但不能同时存在。

import argparse parser = argparse.ArgumentParser() group = parser.add_mutually_exclusive_group() group.add_argument("-f", "--foo") group.add_argument("-b", "--bar") args = parser.parse_args() print("foo = ", args.foo) print ("bar = ", args.bar)
python散装笔记——83: 解析命令行参数

如果尝试运行脚本,同时指定 –foo–bar 参数,脚本将发出以下抱怨信息。

error: argument -b/--bar: not allowed with argument -f/--foo

4: 使用 docopt 的基本示例

docopt 颠覆了命令行参数解析。你只需编写程序的用法字符串,而无需解析参数,docopt 会解析用法字符串,并用它提取命令行参数。

""" Usage: script_docopt.py [-a] [-b] <path> Options: -a Print all the things. -b Get more bees into the path. """ from docopt import docopt if __name__ == "__main__": args = docopt(__doc__) import pprint; pprint.pprint(args)

运行样本:

$ python script_docopt.py Usage: script_docopt.py [-a] [-b] <path> $ python script_docopt.py something {'-a': False, '-b': False, '<path>': 'something'} $ python script_docopt.py something -a {'-a': True, '-b': False, '<path>': 'something'} $ python script_docopt.py -b something -a {'-a': True, '-b': True, '<path>': 'something'}

5: 使用 argparse 自定义解析器错误信息

您可以根据脚本需要创建解析器错误信息。这是通过
argparse.ArgumentParser.error 函数
实现的。下面的示例显示了脚本在给出 –foo 而未给出 –bar 时向 stderr 打印用法和错误信息的情况。

import argparse parser = argparse.ArgumentParser() parser.add_argument("-f", "--foo") parser.add_argument("-b", "--bar") args = parser.parse_args() if args.foo and args.bar is None: parser.error("--foo requires --bar. You did not specify bar.") print("foo =", args.foo) print("bar =", args.bar)

假设脚本名为 sample.py,并运行 python sample.py –foo ds_in_fridge.

这个脚本会发出如下提示:

usage: sample.py [-h] [-f FOO] [-b BAR] sample.py: error: --foo requires --bar. You did not specify bar.
python散装笔记——83: 解析命令行参数

6: 使用 argparse.add_argument_group() 对参数进行概念分组

当你创建 argparse ArgumentParser() 并使用‘-h’运行程序时,你会收到一条自动使用信息,解释你可以使用哪些参数运行软件。默认情况下,位置参数和条件参数被分为两类,例如,下面是一个小脚本(example.py)和运行 python example.py -h 时的输出。

import argparse parser = argparse.ArgumentParser(description='Simple example') parser.add_argument('name', help='Who to greet', default='World') parser.add_argument('--bar_this') parser.add_argument('--bar_that') parser.add_argument('--foo_this') parser.add_argument('--foo_that') args = parser.parse_args() usage: example2.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT] [--foo_this FOO_THIS] [--foo_that FOO_THAT] name Simple example positional arguments: name Who to greet optional arguments: -h, --help show this help message and exit --bar_this BAR_THIS --bar_that BAR_THAT --foo_this FOO_THIS --foo_that FOO_THAT

在某些情况下,你需要将参数分成更多的概念部分来帮助用户。例如,你可能希望将所有输入选项放在一组,而将所有输出格式化选项放在另一组。上面的示例可以调整为将 –foo_* 参数与 –bar_* 参数分开。

import argparse parser = argparse.ArgumentParser(description='Simple example') parser.add_argument('name', help='Who to greet', default='World') # Create two argument groups foo_group = parser.add_argument_group(title='Foo options') bar_group = parser.add_argument_group(title='Bar options') # Add arguments to those groups foo_group.add_argument('--bar_this') foo_group.add_argument('--bar_that') bar_group.add_argument('--foo_this') bar_group.add_argument('--foo_that') args = parser.parse_args()

当运行 python example.py -h 时,会产生这样的输出:

usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT] [--foo_this FOO_THIS] [--foo_that FOO_THAT] name Simple example positional arguments: name Who to greet optional arguments: -h, --help show this help message and exit Foo options: --bar_this BAR_THIS --bar_that BAR_THAT Bar options: --foo_this FOO_THIS --foo_that FOO_THAT
python散装笔记——83: 解析命令行参数

7: 使用 docopt 和 docopt_dispatch 的高级示例

docopt 一样,使用 [docopt_dispatch] 时,你要在入口点模块的 __doc__ 变量中制作你的 –help。在那里,你以 doc string 作为参数调用 dispatch,这样它就可以运行解析器了。

这样,你就不用手动处理参数(通常会导致高循环的 if/else 结构),而只需让调度给出你想如何处理参数集。

这就是 dispatch.on 装饰器的作用:您只需向它提供应触发函数的参数或参数序列,该函数就会以匹配值作为参数执行。

"""Run something in development or production mode. Usage: run.py --development <host> <port> run.py --production <host> <port> run.py items add <item> run.py items delete <item> """ from docopt_dispatch import dispatch @dispatch.on('--development') def development(host, port, kwargs): print('in *development* mode') @dispatch.on('--production') def development(host, port, kwargs): print('in *production* mode') @dispatch.on('items', 'add') def items_add(item, kwargs): print('adding item...') @dispatch.on('items', 'delete') def items_delete(item, kwargs): print('deleting item...') if __name__ == '__main__': dispatch(__doc__)

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/169526.html

(0)
上一篇 2025-02-08 14:00
下一篇 2025-02-08 14:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信