标签归档:optparse

Python argparse忽略无法识别的参数

问题:Python argparse忽略无法识别的参数

Optparse,旧版本只是忽略所有无法识别的参数并继续执行。在大多数情况下,这不是理想的,已在argparse中进行了更改。但是在某些情况下,您想忽略任何无法识别的参数并解析您指定的参数。

例如:

parser = argparse.ArgumentParser()
parser.add_argument('--foo', dest="foo")
parser.parse_args()

$python myscript.py --foo 1 --bar 2
error: unrecognized arguments: --bar

反正有覆盖吗?

Optparse, the old version just ignores all unrecognised arguments and carries on. In most situations, this isn’t ideal and was changed in argparse. But there are a few situations where you want to ignore any unrecognised arguments and parse the ones you’ve specified.

For example:

parser = argparse.ArgumentParser()
parser.add_argument('--foo', dest="foo")
parser.parse_args()

$python myscript.py --foo 1 --bar 2
error: unrecognized arguments: --bar

Is there anyway to overwrite this?


回答 0

更换

args = parser.parse_args()

args, unknown = parser.parse_known_args()

例如,

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
args, unknown = parser.parse_known_args(['--foo', 'BAR', 'spam'])
print(args)
# Namespace(foo='BAR')
print(unknown)
# ['spam']

Replace

args = parser.parse_args()

with

args, unknown = parser.parse_known_args()

For example,

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
args, unknown = parser.parse_known_args(['--foo', 'BAR', 'spam'])
print(args)
# Namespace(foo='BAR')
print(unknown)
# ['spam']

回答 1

parser.add_argument('args', nargs=argparse.REMAINDER)如果要使用它们,可以将其余部分放入新的参数中。

You can puts the remaining parts into a new argument with parser.add_argument('args', nargs=argparse.REMAINDER) if you want to use them.


回答 2

实际上,argparse仍然“忽略” _unrecognized_args。只要这些“无法识别”的参数不使用默认前缀,您就不会听到解析器的任何抱怨。

parse.parse_args()如果要使用以下参数执行程序,请使用@anutbu的配置,但使用standard 。

$ program --foo BAR a b +cd e

我们将使用此具有命名空间的数据集合。

Namespace(_unrecognized_args=['a', 'b', '+cd', 'e'], foo='BAR')

如果我们想-忽略默认前缀,我们可以更改ArgumentParser并决定将+“ a” 用作我们的“可识别”参数。

parser = argparse.ArgumentParser(prefix_chars='+')
parser.add_argument('+cd')

相同的命令将产生

Namespace(_unrecognized_args=['--foo', 'BAR', 'a', 'b'], cd='e')

把它放到你的烟斗里然后抽烟=)

欢乐!

Actually argparse does still “ignore” _unrecognized_args. As long as these “unrecognized” arguments don’t use the default prefix you will hear no complaints from the parser.

Using @anutbu’s configuration but with the standard parse.parse_args(), if we were to execute our program with the following arguments.

$ program --foo BAR a b +cd e

We will have this Namespaced data collection to work with.

Namespace(_unrecognized_args=['a', 'b', '+cd', 'e'], foo='BAR')

If we wanted the default prefix - ignored we could change the ArgumentParser and decide we are going to use a + for our “recognized” arguments instead.

parser = argparse.ArgumentParser(prefix_chars='+')
parser.add_argument('+cd')

The same command will produce

Namespace(_unrecognized_args=['--foo', 'BAR', 'a', 'b'], cd='e')

Put that in your pipe and smoke it =)

nJoy!


为什么要使用argparse而不是optparse?

问题:为什么要使用argparse而不是optparse?

我注意到Python 2.7文档还包含另一个命令行解析模块。除了getoptoptparse我们现在有argparse

为什么还要创建另一个命令行解析模块?为什么要使用它代替optparse?我应该了解一些新功能吗?

I noticed that the Python 2.7 documentation includes yet another command-line parsing module. In addition to getopt and optparse we now have argparse.

Why has yet another command-line parsing module been created? Why should I use it instead of optparse? Are there new features that I should know about?


回答 0

从python开始2.7optparse已弃用,希望将来会消失。

argparse由于其原始页面(https://code.google.com/archive/p/argparse/)上列出的所有原因而更好:

  • 处理位置参数
  • 支持子命令
  • 允许其他可选前缀,例如+/
  • 处理零个或多个和一个或多个样式参数
  • 产生更多有用的使用信息
  • 为自定义类型和操作提供更简单的界面

PEP 389中也提供了更多信息,它是将argparse其纳入标准库的工具。

As of python 2.7, optparse is deprecated, and will hopefully go away in the future.

argparse is better for all the reasons listed on its original page (https://code.google.com/archive/p/argparse/):

  • handling positional arguments
  • supporting sub-commands
  • allowing alternative option prefixes like + and /
  • handling zero-or-more and one-or-more style arguments
  • producing more informative usage messages
  • providing a much simpler interface for custom types and actions

More information is also in PEP 389, which is the vehicle by which argparse made it into the standard library.


回答 1

为什么要使用它代替optparse?是我应该知道的新功能吗?

我认为,@ Nicholas的答案可以很好地解决这一问题,但您不能从以下的“元”问题开始:

为什么还要创建另一个命令行解析模块?

将任何有用的模块添加到标准库中时,这就是两难的境地:当出现一种提供更好的,但向后不兼容的,提供相同功能的方法时,您该怎么办?

您要么坚持旧的,公认的超越方式(通常在谈论复杂的软件包时:异步,扭曲,tkinter,wx或Qt等),要么最终以多种不兼容的方式完成同一件事(XML与命令行解析器相比,恕我直言的解析器是一个更好的例子-但email与处理类似问题的无数旧方法相比,程序包和它们之间的距离也不远;-)。

您可能会在文档中对过时的“过时”方式进行抱怨,但是(只要需要保持向后兼容性)就不能真正消除它们,而必须停止大型的重要应用程序迁移到较新的Python版本。

(第二个难题,与您的问题没有直接关系,总结成一句老话:“标准库是好的软件包将要消亡的地方……”每年约有一半的版本发布,但不是非常好的软件包,非常稳定,不需要经常发布的版本,实际上可能会因为在标准库中被“冻结”而遭受严重损失……但这确实是一个不同的问题)。

Why should I use it instead of optparse? Are their new features I should know about?

@Nicholas’s answer covers this well, I think, but not the more “meta” question you start with:

Why has yet another command-line parsing module been created?

That’s the dilemma number one when any useful module is added to the standard library: what do you do when a substantially better, but backwards-incompatible, way to provide the same kind of functionality emerges?

Either you stick with the old and admittedly surpassed way (typically when we’re talking about complicated packages: asyncore vs twisted, tkinter vs wx or Qt, …) or you end up with multiple incompatible ways to do the same thing (XML parsers, IMHO, are an even better example of this than command-line parsers — but the email package vs the myriad old ways to deal with similar issues isn’t too far away either;-).

You may make threatening grumbles in the docs about the old ways being “deprecated”, but (as long as you need to keep backwards compatibility) you can’t really take them away without stopping large, important applications from moving to newer Python releases.

(Dilemma number two, not directly related to your question, is summarized in the old saying “the standard library is where good packages go to die”… with releases every year and a half or so, packages that aren’t very, very stable, not needing releases any more often than that, can actually suffer substantially by being “frozen” in the standard library… but, that’s really a different issue).


回答 2

添加Python原理的最佳来源是其PEP: PEP 389:argparse-新的命令行解析模块,尤其是标题为“ 为什么getopt和optparse不够?”的部分。

The best source for rationale for a Python addition would be its PEP: PEP 389: argparse – New Command Line Parsing Module, in particular, the section entitled, Why aren’t getopt and optparse enough?


回答 3

街上也有新孩子!

  • 除了已经提到的过时的optparse。[不使用]
  • argparse还提到了,这是不愿意包含外部库的人们的解决方案。
  • docopt是值得研究的外部库,它使用文档字符串作为输入的解析器。
  • click也是外部库,并使用修饰符定义参数。(我的来源建议:为什么单击
  • python-inquirer用于选择工具,基于Inquirer.js(repo

如果你需要一个更深入的比较,请阅读,你可能最终使用docopt点击。感谢Kyle Purdon!

There are also new kids on the block!

  • Besides the already mentioned deprecated optparse. [DO NOT USE]
  • argparse was also mentioned, which is a solution for people not willing to include external libs.
  • docopt is an external lib worth looking at, which uses a documentation string as the parser for your input.
  • click is also external lib and uses decorators for defining arguments. (My source recommends: Why Click)
  • python-inquirer For selection focused tools and based on Inquirer.js (repo)

If you need a more in-depth comparison please read this and you may end up using docopt or click. Thanks to Kyle Purdon!


回答 4

起初,我像@fmark一样不愿意从optparse切换到argparse,因为:

  1. 我以为差异不是很大。
  2. 默认情况下,相当多的VPS仍提供Python 2.6。

然后我看到了这个文档,argparse胜过optparse,尤其是在谈论生成有意义的帮助消息时: http //argparse.googlecode.com/svn/trunk/doc/argparse-vs-optparse.html

然后我看到@Nicholas的“ argparse vs. optparse ”,说我们可以在python <2.7中使用argparse(是的,我以前不知道。)

现在,我的两个问题得到了很好的解决。我写这个希望是希望它可以帮助具有类似心态的其他人。

At first I was as reluctant as @fmark to switch from optparse to argparse, because:

  1. I thought the difference was not that huge.
  2. Quite some VPS still provides Python 2.6 by default.

Then I saw this doc, argparse outperforms optparse, especially when talking about generating meaningful help message: http://argparse.googlecode.com/svn/trunk/doc/argparse-vs-optparse.html

And then I saw “argparse vs. optparse” by @Nicholas, saying we can have argparse available in python <2.7 (Yep, I didn’t know that before.)

Now my two concerns are well addressed. I wrote this hoping it will help others with a similar mindset.