如何使用argparse解析带前导负号的定位参数(负数)

20 投票
3 回答
14332 浏览
提问于 2025-04-17 14:44

我想要解析一个必需的位置参数,这个参数是一个用逗号分隔的整数列表。如果第一个整数前面有一个负号('-'),那么argparse就会报错:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('positional')
parser.add_argument('-t', '--test', action='store_true')
opts = parser.parse_args()
print opts

$ python example.py --test 1,2,3,4
Namespace(positional='1,2,3,4', test=True)

$ python example.py --test -1,2,3,4
usage: example.py [-h] [-t] positional
example.py: error: too few arguments

$ python example.py --test "-1,2,3,4"
usage: example.py [-h] [-t] positional
example.py: error: too few arguments

我看到有人建议使用其他字符来代替-作为标志字符,但我不想这样做。有没有其他方法可以配置argparse,让--test-1,2,3,4都能作为有效的参数呢?

3 个回答

0

我在别的帖子里看到这个,觉得应该更新一下,以便下次我搜索解决这个问题的时候能找到。

$ python example.py --test=-1,2,3,4

理论上应该能工作,我用一个单独的输入测试过,确实有效,比如说

$ python example.py --test=-1
9

来自文档的内容:

parse_args()这个方法会尽量在用户明显犯错的时候给出错误提示,但有些情况本身就比较模糊。例如,命令行参数-1可能是想指定一个选项,也可能是想提供一个位置参数。parse_args()在这里比较小心:位置参数只有在看起来像负数的情况下,才可以以-开头,并且解析器中不能有看起来像负数的选项。

因为-1,2,3,4看起来像负数,所以你必须用--来“转义”它,就像在大多数*nix系统中一样。

另外一个解决方案是使用nargs来处理位置参数,并将数字用空格分开传递:

#test.py
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('positional', nargs='*') #'+' for one or more numbers

print parser.parse_args()

输出:

$ python test.py -1 2 3 -4 5 6
Namespace(positional=['-1', '2', '3', '-4', '5', '6'])

还有第三种方法可以实现你的需求,那就是用parse_known_args代替parse_args。你不需要把位置参数添加到解析器中,而是手动解析它:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--test', action='store_true')

parsed, args = parser.parse_known_args()
print parsed
print args

结果:

$ python test.py  --test -1,2,3,4                                            
Namespace(test=True)
['-1,2,3,4']    

这样做的缺点是帮助文本会变得不那么详细。

33

你需要在命令行参数中插入一个 --

$ python example.py --test -- -1,2,3,4
Namespace(positional='-1,2,3,4', test=True)

这个双破折号的作用是告诉程序,后面不再寻找其他可选的参数了;这是处理这种情况的标准做法,很多命令行工具都是这样使用的。

撰写回答