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

331
我注意到Python 2.7文档中包含了另一个命令行解析模块。除了getoptoptparse之外,现在我们还有argparse
为什么会创建另一个命令行解析模块?我为什么应该使用它而不是optparse?是否有新功能我需要知道的?

8
也许不需要使用其他的模块,因为自从2012年起,Python有一个易用、强大且非常酷的参数解析模块叫做docopt。http://docopt.org - ndemou
1
尝试点击它是optparse的包装器。 - Amit Tripathi
5个回答

360

从Python 2.7开始,optparse已经被弃用,并且希望将来会消失。

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

  • 处理位置参数
  • 支持子命令
  • 允许备选选项前缀,如+/
  • 处理零个或多个和一个或多个样式参数
  • 生成更详细的使用消息
  • 提供了一个更简单的界面,用于自定义类型和操作

更多信息还在PEP 389中,这是使argparse进入标准库的方式。


23
对于自定义类型,接口更简单了... 但总体上接口更复杂了。我真的很奇怪为什么要切换到optparse,因为鼓声getopt将保留。是的,这种陈旧的方式没有被弃用。唉。 - Jürgen A. Erhard
4
在PEP中提到optparse的“纯洁性”,然后又讨论了如何增加其复杂性,这使得它听起来像是被编码成像石头一样灵活(很差)。 - Nick T
1
子命令界面很差。默认输出无用,而且更改它很困难。 - anatoly techtonik
请注意,code.google.com 将在几天内进行维护。更多详细信息可在此处找到:https://argparse.googlecode.com/svn/trunk/doc/argparse-vs-optparse.html - Jean-Francois T.

67
我应该使用什么,而不是optparse?有我应该知道的新功能吗?
@Nicholas的答案很好地回答了这个问题,但没有回答你开始时更“元”的问题:
为什么又创建了一个命令行解析模块?
这是任何有用程序库添加到标准库时的第一个困境:当出现一种更好的但不兼容的方式来提供相同类型的功能时,你应该怎么办?
要么坚持旧的、显然已经过时的方式(通常是当我们谈论复杂的包时:asyncore vs twisted,tkinter vs wx或Qt等),要么就会有多个不兼容的方式来做同样的事情(在我看来,XML解析器比命令行解析器更好的例子——但是与处理类似问题的各种老方法相比,email包也不太远)。
你可能会在文档中威胁说旧方法被“废弃”,但是(只要你需要保持向后兼容性),你无法真正去掉它们,否则会阻止大型重要应用程序转移到更新的Python版本。

不可否认,在 Python 2.7 之前的安装中可以包括 argparse.py,并且不必担心向后不兼容的更改。这是要跟踪的额外事项,但它仍然在 argparse.googlecode.com 的标准库之外维护。 - Ehtesh Choudhury
2
Argparse 在某些(小众?)用途上明显更好。它在绝对意义上并不比 optparse 更好,而是不同。它可以做一些 optparse 无法做到的事情,但也有退步。我刚遇到的一个例子:optparse 默认处理“--”(不确定它是否按照预期执行),而 argparse 对此一无所知。 - Jürgen A. Erhard
对于那些晚来看这条评论的人,argparse 可以帮你设置前缀和名称,大多数解析器都是写成 parser.add_argument('--long-opt', '-l',...) 的形式;'--' 很容易处理,而且可以按照你喜欢的方式进行设置。 - SilverbackNet
@SilverbackNet:看起来你对“--”的含义有所误解。对于标准Unix命令参数解析,一个独立的“--”(不作为前缀)意味着其后面的内容即使以破折号开头也不再是选项。 - kriss
可以从cpython中解除长期弃用的库。无法迁移到更好的捆绑替代方案的大型重要应用程序可以从pypi中获取它们,而其他人则可以从更小的安装中受益。 - Alice Purcell

41

22

这里还有一些新的选择!

  • 除了已经提到过的过时的 optparse [请不要使用]
  • argparse 也被提及,对于不想要引入外部库的人来说,这是一个解决方案。
  • docopt 是一个值得关注的外部库,它使用文档字符串作为输入解析器。
  • click 也是一个外部库,它使用装饰器来定义参数。(我的源推荐:Why Click
  • python-inquirer 面向选择工具并基于 Inquirer.js (repo)

如果您需要更深入的比较,请阅读此篇文章,您可能会使用docoptclick。感谢Kyle Purdon!


4
虽然这是一个有价值的评论,但它更像是一条评论而不是答案。我不会投反对票,但也不会点赞!请用一份有价值的摘要扩展您的回答,使其成为真正的答案!文章链接:https://meta.stackexchange.com/a/8259/172394 - Stefano
1
我试图在我的链接中包含一个摘要,希望现在它值得成为一个很好的stackoverflow回答。 - lony
仅仅是一个快速的补充,检查最后更新
  • argparse 2023 (https://github.com/python/cpython/blob/3.11/Lib/argparse.py).
  • docopt 2018 (https://github.com/docopt/docopt).
  • invoke 2023 (https://pypi.org/project/invoke/#history)
我建议使用argparse,因为它已经被包含在所有版本中作为默认选项,这样更加安全。
- mirageglobe

6
起初我像@fmark一样不太愿意从optparse转换到argparse,因为:
  1. 我认为两者之间的差异并不是很大。
  2. 相当多的VPS仍然默认提供Python 2.6。
然后我看到了这个文档,argparse在生成有意义的帮助信息方面表现优异:http://argparse.googlecode.com/svn/trunk/doc/argparse-vs-optparse.html 接着我看到了@Nicholas的"argparse vs. optparse",说我们可以在python <2.7中使用argparse(是的,我以前不知道。)
现在我的两个顾虑都得到了解决。我写这篇文章希望能帮助那些有类似想法的人。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接