328

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?

roguesys
  • 219
  • 1
  • 6
fmark
  • 57,259
  • 27
  • 100
  • 107

5 Answers5

356

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.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Nicholas Knight
  • 15,774
  • 5
  • 45
  • 57
  • 23
    A much simpler interface for custom types... but a more complex interface overall. I really do wonder why I even switched to optparse, because *drumroll* getopt will *stay*. Yup, no deprecation for that dinosaur. Sheeesh. – Jürgen A. Erhard Mar 10 '11 at 11:33
  • 4
    The mention of "purity" of `optparse` in the PEP then later arguments about how complex it is to add on to makes it sound like it was coded to be as flexible as rock (poorly). – Nick T Aug 26 '13 at 20:12
  • 1
    The subcommands interface is poor. Default output is not useful and changing it is hard. – anatoly techtonik Mar 06 '15 at 08:55
  • Note that code.google.com will go on Maintenance in few days. Differences with more details are available here: https://argparse.googlecode.com/svn/trunk/doc/argparse-vs-optparse.html – Jean-Francois T. Aug 19 '15 at 11:00
67

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).

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • Admittedly, you can include argparse.py for python installations before 2.7 and not worry about backwards-incompatible changes. Extra thing to track, but it is still maintained outside of the standard library at argparse.googlecode.com – Ehtesh Choudhury Jan 15 '13 at 05:23
  • 2
    Argparse is substantially better only for some (niche?) uses. It's not really better in absolute terms, it's *different*. It can do things optparse can't, but it also has regressions. One example I just ran into: optparse handled "--" by default (not sure it did what this is supposed to do) while argparse doesn't know anything of it. – Jürgen A. Erhard Oct 29 '14 at 08:54
  • For anyone coming to the above comment late, argparse has you set the prefix and the name, and most parsers are written as `parser.add_argument('--long-opt', '-l',...)`; '--' is handled easily, and however you like. – SilverbackNet Jan 30 '20 at 06:59
  • @SilverbackNet: looks like you missed the point about '--'. For standard Unix commands arguments parsing, an occurence of '--' (by itself, not as a prefix) means what follows are not options any more even if they begin with dashes. – kriss Jan 04 '21 at 09:44
  • One could unbundle long-deprecated libraries from cpython. Large, important applications that couldn't migrate to the better, bundled replacement could just pull them from pypi, and everyone else would benefit from a smaller installation. – Alice Purcell Dec 31 '21 at 08:10
41

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?

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
22

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!

lony
  • 6,733
  • 11
  • 60
  • 92
  • 4
    while this is a worthwhile comment, it still is a comment more than an answer.. no downvote but no upvote for me either! Expand your answer with a valuable summary of the article to make it into a real answer!: https://meta.stackexchange.com/a/8259/172394 – Stefano Jun 14 '17 at 15:41
  • 1
    I tried to include a summary of my link I hope now it is worth a good stackoverflow answer. – lony Jan 26 '18 at 14:28
  • just a quick addition, checking the last update - 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) I would stick to argparse, included default as part of all versions to be safe. – mirageglobe Mar 18 '23 at 18:34
6

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.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
RayLuo
  • 17,257
  • 6
  • 88
  • 73