65

当我运行时parsePlotSens.py -s bw hehe,它说这hehe是一个无法识别的论点。但是,如果我运行parsePlotSens.py hehe -s bw,就可以了。理想情况下,我希望它适用于这两种情况。

有小费吗?以下是我的代码:

if __name__ == '__main__' :

    parser = argparse.ArgumentParser(prog='parsePlotSens');
    parser.add_argument('-s', '--sort', nargs =1, action = 'store', choices = ['mcs', 'bw'], default='mcs', help=sorthelp)
    parser.add_argument('filename', nargs ='+', action = 'store')
    option = parser.parse_args(sys.argv)
4

6 回答 6

84

不要sys.argv作为参数传递给parse_args. 只需使用

option = parser.parse_args()

如果您确实传递sys.argvparse_args,则脚本本身的路径或名称是第一项sys.argv,因此成为 的值option.filename。然后hehe成为一个未知的论点。

如果省略sys.argv则按预期parse_args解析。sys.argv

于 2013-06-15T00:35:27.837 回答
52

您可以通过允许未知参数来解决此问题

代替

args = parser.parse_args()

args, unknown = parser.parse_known_args()
于 2018-01-02T07:58:14.493 回答
6

此外,作为对 unutbu 答案的补充,以这种方式将参数存储在字典中使测试变得容易:

args = vars(parser.parse_args())
print args

打印字典:

{'sort': ['bw'], 'filename': ['hehe']}

喜欢 :

if args['sort'] == 'bw':
    # code here

...
于 2013-06-15T00:24:12.440 回答
2

我的情况与问题不同,但错误相同。

我的情况:

  1. 我有一个带有 windows pycharm 的远程开发(SFTP),并上传以在 linux 上运行。
  2. \python命令在我的bash文件中有一些换行符,比如

    python args_config.py \
        --arg1="hello" \
        --arg2="world"
    

并引发python argparse: unrecognized argumentsargs not found 错误。

问题是 Windows 和 linux 中的 bash 文件换行不同,

只是用pycharm设置File -> Line Separators -> LF - Unix and OS X (\n)

上传到 linux 并运行 bash 文件,它可以工作了!

于 2018-11-10T08:56:21.267 回答
1

为了在此处完成此答案,我提供了一个示例来获取和解析未知参数:


import argparse

parser = argparse.ArgumentParser()
# we only have a know argument  as key-pair --known KNOWN
parser.add_argument('--known')

# test with known un unknown variables
args, unknown = parser.parse_known_args(["--known", "var", "--unknown", "bar", "--flag"])

unknown返回一个类似的列表["--unknown", "bar", "--flag"]。我们只需要解析它:

keypairs = dict([unknown[i:i+2] for i in range(0, len(unknown), 1) if unknown[i].startswith("--") and not (unknown[i+1:i+2]+["--"])[0].startswith("--")])

flags = [unknown[i] for i in range(0, len(unknown), 2) if (unknown[i+1:i+2]+["--"])[0].startswith("--")]
于 2019-08-20T21:18:06.657 回答
0

非常有用的线程。我和@Yan Zhu、@unutbu 和@FacePalm 的问题几乎相同,但我也需要接受 argv。我想出了这个,很好,因为它允许我编写不需要 sys.argv 参数的单元测试。

import argparse, sys


def parse(arg_list):
     p = argparse.ArgumentParser(description="my simple app")
     p.add_argument('-z', '--zeta', type=str, default='[zeta from default]')
     p.add_argument('-a', '--application', type=str, default='[application from default]')
     return p.parse_known_args(arg_list)


code_args = [ '-a', 'a from code', '-q', 'q from code', '-o', 'o from code']

print(parse(code_args + sys.argv[1:]))

当您像这样从 intellij 添加运行时参数时-a 'a from intellij',结果看起来像这样。

/usr/local/bin/python3.7 /Users/me/IdeaProjects/co-util-py/test/varargstest.py -a "a from intellij"

(Namespace(application='a from intellij', other='o from code'), ['-q', 'q from code'])

您可以看到 argparse 不会删除 q,但它也不会解析它。

此外,经过大量的大脑疲劳和测试,sys.argv 和创建的列表之间唯一真正的区别sys.argv[0]是正在调用的程序的名称。从列表中删除它并不重要。

于 2020-05-04T17:03:19.777 回答