Python argparse: 无法识别的参数

当我运行 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)
138824 次浏览

另外,作为对 unutbu 答案的补充,以这种方式在字典中存储参数可以使测试变得简单:

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

打印字典:

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

比如:

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


...

不要将 sys.argv作为参数传递给 parse_args

option = parser.parse_args()

如果将 sys.argv传递给 parse_args,那么脚本本身的路径或名称就是 sys.argv中的第一项,因此就成为 option.filename的值。然后 hehe变成一个未知参数。

如果省略 sys.argv,那么 parse_args将按预期解析 sys.argv

您可以通过允许未知参数来绕过这个问题

替换

args = parser.parse_args()

args, unknown = parser.parse_known_args()

我的情况和问题不一样,但是错误是一样的。

我的情况:

  1. 我有一个远程开发人员(SFTP)与 Windowspycharm,并上传到运行 linux。
  2. Python 命令与 bash 文件中的 \有一些换行符,如

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

and raise a python argparse: unrecognized arguments args not found error.

the problem is the bash file line breaking is different in windows and linux,

just setting with pycharm File -> Line Separators -> LF - Unix and OS X (\n)

upload to linux and run bash file, it works!

为了完成这个 回答,我在这里提供了一个获取和解析未知参数的示例:


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", "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("--")]

非常有用的线。我的问题和@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]是被调用的程序的名称。把这个从名单上去掉,就没关系了。