python argparse:无法识别的参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17118999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 00:31:07  来源:igfitidea点击:

python argparse: unrecognized arguments

pythonargparse

提问by Yan Zhu

When I run parsePlotSens.py -s bw hehe, it says that heheis an unrecognized argument. However, if I run parsePlotSens.py hehe -s bw, it's OK. Ideally, I would like it work for both cases.

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

Any tips? The following is my code:

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

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)

采纳答案by unutbu

Do not pass sys.argvas an argument to parse_args. Just use

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

option = parser.parse_args()

If you do pass sys.argvto parse_args, then the path or name of the script itself is the first item in sys.argvand thus becomes the value of option.filename. The hehethen becomes an unknown argument.

如果确实传递sys.argvparse_args,则脚本本身的路径或名称是 中的第一项sys.argv,因此成为 的值option.filename。在hehe随后变成未知参数。

If you omit sys.argvthen parse_argsparses sys.argvas expected.

如果省略sys.argvparse_args分析sys.argv预期。

回答by Gauthier Boaglio

Also, as a complement to unutbu's answer, storing the arguments in a dictionary this way makes the tests easy:

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

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

Prints the dictionary:

打印字典:

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

Like :

喜欢 :

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

...

回答by FacePalm

You can get around this by allowing unknown arguments

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

Replace

代替

args = parser.parse_args()

with

args, unknown = parser.parse_known_args()

回答by Colin Wang

My situation not same with the question, but the error is same.

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

My situation:

我的情况:

  1. I have a remote dev(SFTP) with windows pycharm, and upload to run with linux.
  2. the python command have some line break with \in my bash file, like

    python args_config.py \
        --arg1="hello" \
        --arg2="world"
    
  1. 我有一个带有 Windows pycharm 的远程开发(SFTP),并上传以在 linux 上运行。
  2. python 命令\在我的 bash 文件中有一些换行符,比如

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

and raise a python argparse: unrecognized argumentsargs not found error.

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

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

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

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

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

upload to linux and run bash file, it works!

上传到 linux 并运行 bash 文件,它有效!

回答by aitorhh

To complete this answerhere I provide an example to get and parse the unknown arguments:

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


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

unknownreturn a list like ["--unknown", "bar", "--flag"]. We just need to parse it:

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

回答by Tony Fraser

Very useful thread. I had pretty much the same question as @Yan Zhu, @unutbu and @FacePalm's answeres were good, but I need to take in argv also. I came up with this, figured good because it allows me to write unit tests that don't require sys.argv arguments.

非常有用的线程。我和@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:]))

When you add a runtime param from intellij like this -a 'a from intellij'the results look like so.

当您像这样从 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'])

You can see that argparse doesn't drop the q, but it also doesn't parse it.

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

Also, after lots of brain strain and testing, the only real difference between sys.argv and a list created is that sys.argv[0]is the name of the program that is being called. Drop that from the list and it doesn't matter.

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