Python command line tour: delving into argparse (2)

Time:2020-4-4

By hellogithub-Prodesire

Preface

In the previous article “delving into argparse (I)”, we learned more aboutargparseIts basic functions include parameter actions and parameter categories. It has the ability to write a simple command line program. This article will continue to exploreargparseThe advanced method of playing, a glimpse of its full picture, helps us to have the ability to implement complex command-line programs.

Python 3 is the default interpreter for this series of articles.
If you are still using Python 2, please pay attention to the differences in syntax and library usage between the two~

Help

Auto generate help

When you specify-hor--helpParameter, the help information will be output. andargparseCan be specified byadd_helpParticipation isTrueOr not specified to output help information automatically.

>>> import argparse
>>> parser = argparse.ArgumentParser(add_help=True)
>>> parser.add_argument('--foo')
>>> parser.parse_args(['-h'])
usage: [-h] [--foo FOO]

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO

Ifadd_help=False, then specify-hError will be reported:

>>> import argparse
>>> parser = argparse.ArgumentParser(add_help=False)
>>> parser.add_argument('--foo')
>>> parser.parse_args(['-h'])
usage: [--foo FOO]
: error: unrecognized arguments: -h

Custom Help

ArgumentParserUseformatter_classThe input parameter controls the output help format.
For example, by specifyingformatter_class=argparse.RawTextHelpFormatter, we can make help content follow the original format:

>>> import argparse
>>> parser = argparse.ArgumentParser(
...     add_help=True,
...     formatter_class=argparse.RawTextHelpFormatter,
...     description="""
...     description
...         raw
...            formatted"""
... )
>>> parser.add_argument(
...     '-a', action="store_true",
...     help="""argument
...         raw
...             formatted
...     """
... )
>>>
>>> parser.parse_args(['-h'])
usage: [-h] [-a]

    description
        raw
           formatted

optional arguments:
  -h, --help  show this help message and exit
  -a          argument
                      raw
                          formatted

Not specified under comparisonformatter_classYou can find the difference between description and – A in the help output of

>>> import argparse
>>> parser = argparse.ArgumentParser(
...     add_help=True,
...     description="""
...     description
...         notraw
...            formatted"""
... )
>>> parser.add_argument(
...     '-a', action="store_true",
...     help="""argument
...         notraw
...             formatted
...     """
... )
>>> parser.parse_args(['-h'])
usage: [-h] [-a]

description notraw formatted

optional arguments:
  -h, --help  show this help message and exit
  -a          argument notraw formatted

Parameter group

Sometimes, we need to group the parameters so that the help information can be displayed together.

For example, a command line supports three parameter options--user--passwordand--push, the first two need to be placed in aauthenticationTo indicate that they are authentication information. Then we can useArgumentParser.add_argument_groupTo satisfy:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> group = parser.add_argument_group('authentication')
>>> group.add_argument('--user', action="store")
>>> group.add_argument('--password', action="store")
>>> parser.add_argument('--push', action='store')
>>> parser.parse_args(['-h'])
usage: [-h] [--user USER] [--password PASSWORD] [--push PUSH]

optional arguments:
  -h, --help           show this help message and exit
  --push PUSH

authentication:
  --user USER
  --password PASSWORD

As you can see, when we output help,--userand--passwordOptions appear inauthenticationGroup.

Option parameter prefix

I don’t know if you notice that the option parameter prefixes of command-line programs may be different on different platforms. For example, on UNIX, the prefix is-On windows, most command-line programs (such asfindstr)The option parameter prefix for is/

stayargparseThe option parameter prefix defaults to the UNIX command line convention, which is-。 But it also supports custom prefixes. Here is an example:

>>> import argparse
>>> 
>>> parser = argparse.ArgumentParser(
...     description='Option prefix',
...     prefix_chars='-+/',
... )
>>> 
>>> parser.add_argument('-power', action="store_false",
...                     default=None,
...                     help='Set power off',
...                     )
>>> parser.add_argument('+power', action="store_true",
...                     default=None,
...                     help='Set power on',
...                     )
>>> parser.add_argument('/win',
...                     action="store_true",
...                     default=False)
>>> parser.parse_args(['-power'])
Namespace(power=False, win=False)
>>> parser.parse_args(['+power', '/win'])
Namespace(power=True, win=True)

In this example, we specify three option parameter prefixes-+and/Thus:

  • By specifying option parameters-powerMakepower=False
  • By specifying option parameters+powerMakepower=True
  • By specifying option parameters/winMakewin=True

Shared resolver

Sometimes we need to share the parser to share the parameter configuration. For example, our command-line tool needs to support Alibaba cloud and AWS operations. Both operations need to be specifiedAccessKeyIdandAccessKeySecretTo indicate user identity and permissions. So it is necessary to share the parser, so that the code can be repeated less.

We can do this atbase.pyA parent parser is defined inAccessKeyRelated parameter configuration, as a common parser. Since subsequent child parsers will automatically generate help information, the parent parser here specifiesadd_help=FalseTo not automatically generate help information:

# bash.py
import argparse

parser = argparse.ArgumentParser(add_help=False)

parser.add_argument('--ak-id', action="store")
parser.add_argument('--ak-secret', action="store")

And then we can separateali.pyandaws.pySub parsers are defined inparentsThe input parameter specifies the parent parser mentioned above, so as to inherit the public parameters and implement their own parameters:

# ali.py
import argparse
import base

parser = argparse.ArgumentParser(
    parents=[base.parser],
)

parser.add_argument('--ros',
                    action="store_true",
                    default=False,
                    help='Using ROS service to orchestrate cloud resources')

print(parser.parse_args())
# aws.py
import argparse
import base

parser = argparse.ArgumentParser(
    parents=[base.parser],
)

parser.add_argument('--cloudformation',
                    action="store_true",
                    default=False,
                    help='Using CloudFormation service to orchestrate cloud resources')

print(parser.parse_args())

Finally passed-hSee the parameters separatelyali.pyandaws.pySupported parameters, where common parameters are--ak-idand--ak-secret, specific parameters are--rosand--cloudformation

$ python3 ali.py -h

usage: ali.py [-h] [--ak-id AK_ID] [--ak-secret AK_SECRET] [--ros]

optional arguments:
  -h, --help            show this help message and exit
  --ak-id AK_ID
  --ak-secret AK_SECRET
  --ros                 Using ROS service to orchestrate cloud resources
$ python3 aws.py -h

usage: aws.py [-h] [--ak-id AK_ID] [--ak-secret AK_SECRET] [--cloudformation]

optional arguments:
  -h, --help            show this help message and exit
  --ak-id AK_ID
  --ak-secret AK_SECRET
  --cloudformation      Using CloudFormation service to orchestrate cloud
                        resources

Nested parser

In the command line we introduced earlier, the form of use is usuallycli --a --b xxx。 But one of the most common ways to use the command line iscli subcmd --a --b xxx。 For example, when we want to passgitWhen pushing labels, you will usegit push --tags

By implementing nested parsers, we can easily parse the form of this subcommand.

In the nested parser, we define a parent parser as the entry of the whole command line, and then define n sub parsers respectively to correspond to n sub commands, so that the whole function can be realized.

In the following example, we supportcreateanddeleteTwo subcommands to create or delete the specified path. anddeleteCommand support--recursiveParameter to indicate whether to delete the specified path recursively:

# cli.py
import argparse

parser = argparse.ArgumentParser()

subparsers = parser.add_subparsers(help='commands')

# Create
create_parser = subparsers.add_parser(
    'create', help='Create a directory')
create_parser.add_argument(
    'dirname', action='store',
    help='New directory to create')

# Delete
delete_parser = subparsers.add_parser(
    'delete', help='Remove a directory')
delete_parser.add_argument(
    'dirname', action='store', help='The directory to remove')
delete_parser.add_argument(
    '--recursive', '-r', default=False, action='store_true',
    help='Recursively remove the directory',
)

print(parser.parse_args())

Direct designation-hTo view the supported subcommand and parameter options:

$ python3 cli.py -h

usage: cli.py [-h] {create,delete} ...

positional arguments:
  {create,delete}  commands
    create         Create a directory
    delete         Remove a directory

optional arguments:
  -h, --help       show this help message and exit

Direct designationdelete -hCheck it out.deleteParameter options supported by subcommands:

$ python3 cli.py delete -h

usage: cli.py delete [-h] [--recursive] dirname

positional arguments:
  dirname          The directory to remove

optional arguments:
  -h, --help       show this help message and exit
  --recursive, -r  Recursively remove the directory

Custom actions

In the previous article “in-depth argparse (1)”, we introduced eight kinds of parameter actions, which can be said to cover most scenes. However, some specific requirements cannot be met, such as the parameter values you want to get are all uppercase. In this case, custom actions come in handy.

To implement a custom action class, you need to inherit fromargparse.Action, this custom action class is passed toArgumentParser.add_argumentOfactionParticipation. When the parser parses parameters, it calls the__call__Method whose signature is__call__(self, parser, namespace, values, option_string=None) Among them,

  • Parser is a parser instance
  • Namespace stores parsing results
  • Values is the parameter value passed in from the command line
  • Option string is the parameter option

In the following example, we use the--wordsPass in the word and convert its value to uppercase in the custom action class:

# cli.py
import argparse

class WordsAction(argparse.Action):

    def __call__(self, parser, namespace, values,
                 option_string=None):
        print(f'parser = {parser}')
        print(f'values = {values!r}')
        print(f'option_string = {option_string!r}')

        values = [v.upper() for v in values]
        setattr(namespace, self.dest, values)


parser = argparse.ArgumentParser()
parser.add_argument('--words', nargs='*', action=WordsAction)

results = parser.parse_args()
print(results)
$ python3 cli.py --words foo bar

parser = ArgumentParser(prog='cli.py', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
values = ['foo', 'bar']
option_string = '--words'
Namespace(words=['FOO', 'BAR'])

Subsection

Through rightargparseI’m sure you’ve got a comprehensive understanding of itargparseIt also has the ability to develop command-line tools. But “the paper must come to the end of shallow awareness, never know this matter to be done.”.

In the next article, I will take you to useargparseRealize the commongitCommand, do you think it’s exciting?

Python command line tour: delving into argparse (2)
Welcome to HelloGitHub official account for more open source projects.

“Explain open source project series”Launch – let the people who are interested in the open source project no longer fear, let the initiator of the open source project no longer alone. Following our article, you will find programming fun, easy to use, and easy to participate in open source projects. Welcome to contact us to contribute to us, let more people fall in love with open source, contribute to open source ~

Recommended Today

PHP Basics – String Array Operations

In our daily work, we often need to deal with some strings or arrays. Today, we have time to sort them out String operation <?php //String truncation $str = ‘Hello World!’ Substr ($STR, 0,5); // return ‘hello’ //Chinese string truncation $STR = ‘Hello, Shenzhen’; $result = mb_ Substr ($STR, 0,2); // Hello //First occurrence of […]