Python Argparse:使用单个大头钉作为标志,例如`./myscript -5` 像 Git 和 CoreUtils

Posted

技术标签:

【中文标题】Python Argparse:使用单个大头钉作为标志,例如`./myscript -5` 像 Git 和 CoreUtils【英文标题】:Python Argparse: Using a single tack as a flag, e.g. `./myscript -5` like Git and CoreUtils 【发布时间】:2021-11-01 14:31:23 【问题描述】:

在 Python Argparse 中使用单钉 - 作为标志

许多 GNU CoreUtils(headtail 等)和 Git 都具有命令行功能,可以让您执行例如

$ head -5 ...
$ tail -20 ...
$ git log -5 ...

如何使用Python的argparse模块达到同样的效果?

示例解析器

#!/usr/bin/env python3
import argparse
p = argparse.ArgumentParser()
p.add_argument('-', dest='dash', help='Tell me how many!')
p.add_argument('-n', dest='n', help='This works, but I dislike it!')
p.add_argument('positional', nargs='*')
print(p.parse_intermixed_args())

这会产生用法:

$ ./example.py --help
usage: example.py [-h] [- DASH] [-n N] [positional [positional ...]]

什么有效

使用例如-n5-n=5-n 5 都按预期工作。

$ ./example.py before -n5 after
Namespace(dash=None, n='5', positional=['before', 'after'])

$ ./example.py before -n=5 after
Namespace(dash=None, n='5', positional=['before', 'after'])

$ ./example.py before -n 5 after
Namespace(dash=None, n='5', positional=['before', 'after'])

什么没有按预期工作

在这里,我们可以看到-5 没有按预期工作。令人惊讶的是,- 5 确实有效。

下面的第一个示例是我想要的用法,但结果不是我想要的。

# This does not work, `-5` is considered a positional argument.
# ~~ THIS IS WHAAT I WANT TO HAVE WORK! ~~
$ ./example.py before -5 after
Namespace(dash=None, n=None, positional=['before', '-5', 'after'])

# This works, but is not what I want
$ ./example.py before - 5 after
Namespace(dash='5', n=None, positional=['before', 'after'])

【问题讨论】:

如果你想做一些奇怪的事情,不要使用 argparse! 不认真,我认为您足够聪明,可以编写自己的sys.argv 解析器,或者阅读argparse.py 代码并弄清楚它在这种极端情况下的作用。 git 等不要使用 argparse 【参考方案1】:

如中所述

parser.add_argument('-f', '--foo')

'-f' 是短选项,'--foo' 是长选项。

(First) Long 用于dest,可以用作'--foo=value'。 Short 可以用作 '-fvalue' 或带有 'store_true' 短的 '-bf5'。

但是这种用法是标志使用方式的结果。没有坚持精确语法的前置过滤器。 '-f=value' 应该可以工作,'-foobar' 可以用作 long。

您的 '-' 不符合此记录的模式,并且不能保证无论长短都可以正常工作。

In [1]: import argparse
In [2]: parser=argparse.ArgumentParser()
In [3]: a = parser.add_argument('-','-f','--foo')

In [5]: parser.parse_args(['--foo=5'])
Out[5]: Namespace(foo='5')
In [6]: parser.parse_args(['-f5'])
Out[6]: Namespace(foo='5')
In [7]: parser.parse_args(['-5'])
usage: ipython3 [-h] [- FOO]
ipython3: error: unrecognized arguments: -5
     ...
In [8]: parser.parse_args(['-=5'])
Out[8]: Namespace(foo='5')

看起来 '-' 的处理方式很长。它不能用作短片。

通常argparse 是 POSIX getopt 实践的扩展,但并非所有 Linux 实用程序都使用它(尤其是在 UNIX 开发早期创建的那些)。

【讨论】:

以上是关于Python Argparse:使用单个大头钉作为标志,例如`./myscript -5` 像 Git 和 CoreUtils的主要内容,如果未能解决你的问题,请参考以下文章

播放应用签名以进一步上传 Alpha 大头钉

ArgParse 模块想要在单个命令中使用两个参数

使用 argparse 和 python 接受字典作为参数 [重复]

python argh/argparse:如何将列表作为命令行参数传递?

分发 Python 库(单个文件)

AEJoy —— 表达式之 3D 角点大头针JS