Python Command Line Travel - Deep into argparse

Keywords: Python github less encoding

Author: Hello GitHub-Prodesire

Hello GitHub's "Explaining Open Source Projects" series, project address: https://github.com/HelloGitHu...

Preface

In the first article "A Preliminary Exploration of argparse", we have a preliminary grasp of the use of argparse's tetralogy, which has a basic sense of body.
But what types of parameters does it support? How should these parameters be configured? This article will give you an in-depth understanding of the parameters of argparse.

By default, this series of articles uses Python 3 as an interpreter.
If you're still using Python 2, please note the differences in grammar and library usage between the two.~

Parametric Action

Do you remember? The second step in the previous Quartet is to define parameters. In this step, we specify action parameters:

parser.add_argument('--sum', dest='accumulate', action='store_const',
                    const=sum, default=max,
                    help='sum the nums (default: find the max)')

So what is the action in it, that is, parametric action, used for?

Imagine that when we enter a series of parameters on the command line, we want to do different processing for different types of parameters.
Then the parameter action actually tells the parser how we want the corresponding parameters to be handled. For example, should the parameter value be stored as a value or appended to a list? Is it True, or False?

Parametric actions are divided into the following eight categories:

  • store -- Save the value of the parameter, which is the default parameter action. It is usually used to specify a value for a parameter, such as a name:
>>> parser.add_argument('--name')
>>> parser.parse_args(['--name', 'Eric'])
Namespace(name='Eric')
  • store_const -- Saves the fixed value named by const. When we want to act as a marker by whether or not we have a given parameter, we can use it to act as a marker if we have a given value, such as:
>>> parser.add_argument('--sum', action='store_const', const=sum)
>>> parser.parse_args(['--sum'])
Namespace(sum=<built-in function sum>)
>>> parser.parse_args([])
Namespace(sum=None)
  • store_true and store_false -- are special cases of store_const that are used to store True and False, respectively. If the parameter is specified, the default values are False and True, respectively, such as:
>>> parser.add_argument('--use', action='store_true')
>>> parser.add_argument('--nouse', action='store_false')
>>> parser.parse_args(['--use', '--nouse'])
Namespace(nouse=False, use=True)
>>> parser.parse_args([])
Namespace(nouse=True, use=False)
  • Appnd -- Save the parameter value append to a list. It is often used to allow multiple identical options on the command line, such as:
>>> parser.add_argument('--file', action='append')
>>> parser.parse_args(['--file', 'f1', '--file', 'f2'])
Namespace(file=['f1', 'f2'])
  • append_const -- Adds the fixed value named by const to a list (the default value of const is None). It is often used to save the fixed values of multiple parameters in the same list, and dest is needed to cooperate with each other in order to put them in the same list, such as:

If dest is not specified, the fixed value is stored in a variable named after the parameter name.

>>> parser.add_argument('--int', action='append_const', const=int)
>>> parser.add_argument('--str', action='append_const', const=str)
>>> parser.parse_args(['--int', '--str'])
Namespace(int=[<class 'int'>], str=[<class 'str'>])

Specify dest as a parameter, and the fixed value is stored in the variable named by dest

>>> parser.add_argument('--int', dest='types', action='append_const', const=int)
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.parse_args(['--int', '--str'])
Namespace(types=[<class 'int'>, <class 'str'>])
  • count -- Calculates the number of occurrences of parameters, such as:
>>> parser.add_argument('--increase', '-i', action='count')
>>> parser.parse_args(['--increas', '--increase'])
Namespace(increase=2)
>>>parser.parse_args(['-iii'])
Namespace(increase=3)
  • Help -- Print the complete help information for all options and parameters in the parser and exit.
  • Version -- Print the command line version, specify the version by specifying the version entry parameter, and exit after invocation. Such as:
>>> parser = argparse.ArgumentParser(prog='CMD')
>>> parser.add_argument('--version', action='version', version='%(prog)s 1.0')
>>> parser.parse_args(['--version'])
CMD 1.0

Parameter Categories

If the parameter action defines how the parser handles the parameters after they are received, then the parameter category tells the parser the meta-information of the parameters, that is, what the parameters are like. For example, is the parameter a string? Or the Boolean type? How many values are the parameters optional? Or you can give a value, and so on.

Next, we will introduce different types of parameters one by one.

Optional parameters

Optional parameters, as the name implies, can be added or not. By default, the parameters added through ArgumentParser. add_argumentation are optional parameters.

We can specify short parameters by - or parameters with short names; we can also specify long parameters by - or parameters with long names. Of course, you can specify both.

Optional parameters are usually used: if the user provides a parameter and its corresponding value, the value is used; if not, the default value is used. Such as:

>>> parser.add_argument('--name', '-n')
>>> parser.parse_args(['--name', 'Eric'])  # Specify names by long parameters
Namespace(name='Eric')
>>> parser.parse_args(['-n', 'Eric']) # Specify name by short parameter
Namespace(name='Eric')
>>> parser.parse_args([]) # Default to None if not specified
Namespace(name=None)

Parameter type

The parameter type is what type the parser parameter value is to be parsed as, and by default, the str type. We can specify parameter types by type entry.

argparse supports a variety of parameter types, such as int, float, bool, etc.

>>> parser.add_argument('-i', type=int)
>>> parser.add_argument('-f', type=float)
>>> parser.add_argument('-b', type=bool)
>>> parser.parse_args(['-i', '1', '-f', '2.1', '-b', '0'])
Namespace(b=False, f=2.1, i=1)

Even worse, type entry can also be a callable object. This gives us a lot of imagination. You can specify type=open to process parameter values as files, or you can specify custom functions for type checking and type conversion.

Processing as a document:

>>> parser.add_argument('--file', type=open)
>>> parser.parse_args(['--file', 'README.md'])
Namespace(b=None, f=None, file=<_io.TextIOWrapper name='README.md' mode='r' encoding='cp936'>, i=None)

Uses the custom function to carry on the processing, enters the parameter value, needs to return the transformation result.
For example, for the parameter num, we want to return 1 when its value is less than 1 and 10 when its value is greater than 10:

>>> def limit(string):
...   num = int(string)
...   if num < 1:
...     return 1
...   if num > 10:
...     return 10
...   return num
...
>>> parser.add_argument('--num', type=limit)
>>> parser.parse_args(['--num', '-1'])  # If num is less than 1, then 1
Namespace(num=1)
>>> parser.parse_args(['--num', '15'])  # If num is greater than 10, take 10.
Namespace(num=10)
>>> parser.parse_args(['--num', '5'])  # num is between 1 and 10, and the original value is taken.
Namespace(num=5)

Default values of parameters

The parameter default value is used for the default value when the parameter value is not passed on the command line and can be specified by default. If this value is not specified, the default value of the parameter is None.

For example:

>>> parser.add_argument('-i', default=0, type=int)
>>> parser.add_argument('-f', default=3.14, type=float)
>>> parser.add_argument('-b', default=True, type=bool)
>>> parser.parse_args([])
Namespace(b=True, f=3.14, i=0)

Location parameters

Position parameters specify parameter values by position rather than by the parameters at the beginning of - or - or.

For example, we can specify two location parameters x and y, where the first x is added and the second y is added. So when you type 12 on the command line, it corresponds to x and y, respectively.

>>> parser.add_argument('x')
>>> parser.add_argument('y')
>>> parser.parse_args(['1', '2'])
Namespace(x='1', y='2')

Optional value

The optional value is the content of the parameter value, which is specified by choices.

In some cases, we may need to limit the content of user input parameters, only one of the preset values, then the optional values come in handy.

For example, specify that the file read mode is restricted to read-only and read-write:

>>> parser.add_argument('--mode', choices=('read-only', 'read-write'))
>>> parser.parse_args(['--mode', 'read-only'])
Namespace(mode='read-only')
>>> parser.parse_args(['--mode', 'read'])
usage: [-h] [--mode {read-only,read-write}]
: error: argument --mode: invalid choice: 'read' (choose from 'read-only', 'read-write')

Mutual exclusion parameter

Mutual exclusion parameter means that multiple parameters are mutually exclusive and cannot occur at the same time. Using mutex parameters, first add a mutually exclusive group in the parser through ArgumentParser.add_mutually_exclusive_group, and then add parameters in this group, then all parameters in the group are mutex.

For example, if we want to tell the vehicle we are traveling on the command line, whether it's a car, a bus or a bicycle, then we can write as follows:

>>> group = parser.add_mutually_exclusive_group()
>>> group.add_argument('--car', action='store_true')
>>> group.add_argument('--bus', action='store_true')
>>> group.add_argument('--bike', action='store_true')
>>> parser.parse_args([])  # Nothing to ride
Namespace(bike=False, bus=False, car=False)
>>> parser.parse_args(['--bus'])  # Take the bus
Namespace(bike=False, bus=True, car=False)
>>> parser.parse_args(['--bike'])  # Ride on a bicycle
Namespace(bike=True, bus=False, car=False)
>>> parser.parse_args(['--bike', '--car'])  # If you want to ride a bicycle, and you want to ride a bicycle, you can't.
usage: [-h] [--car | --bus | --bike]
: error: argument --car: not allowed with argument --bike

Variable parameter list

Variable parameter lists are used to define that a parameter can have multiple values, and the number of values can be defined by nargs.

If nargs=N, N is a number, the parameter is required to provide N values, such as:

>>> parser.add_argument('--foo', nargs=2)
>>> print(parser.parse_args(['--foo', 'a', 'b']))
Namespace(foo=['a', 'b'])
>>> print(parser.parse_args(['--foo', 'a', 'b', 'c']))
usage: [-h] [--foo FOO FOO]
: error: unrecognized arguments: c

If nargs=?, the parameter is required to provide 0 or 1 value, such as:

>>> parser.add_argument('--foo', nargs='?')
>>> parser.parse_args(['--foo'])
Namespace(foo=None)
>>> parser.parse_args(['--foo', 'a'])
Namespace(foo='a')
>>> parser.parse_args(['--foo', 'a', 'b'])
usage: [-h] [--foo [FOO]]
: error: unrecognized arguments: b

If nargs=*, the parameter is required to provide zero or more values, such as:

>>> parser.add_argument('--foo', nargs='*')
>>> parser.parse_args(['--foo'])
Namespace(foo=[])
>>> parser.parse_args(['--foo', 'a'])
Namespace(foo=['a'])
>>> parser.parse_args(['--foo', 'a', 'b', 'c', 'd', 'e'])
Namespace(foo=['a', 'b', 'c', 'd', 'e'])

If nargs=?, the parameter is required to provide at least one value, such as:

>>> parser.add_argument('--foo', nargs='+')
>>> parser.parse_args(['--foo', 'a'])
Namespace(foo=['a'])
>>> parser.parse_args(['--foo'])
usage: [-h] [--foo FOO [FOO ...]]
: error: argument --foo: expected at least one argument

Subsection

After knowing the parameters action and parameters category, are we beginning to have a thorough understanding of the use of argparse? At least, it's no longer necessary to use what you've learned to do simple command-line tools.

In the next article, we will continue to understand the functions of argparse, how to modify parameter prefixes, how to define parameter groups, how to define nested parsers, how to write custom actions, etc. Let's wait and see.~


Welcome to Hello GitHub Public Number for more information and content on open source projects

"Explaining Open Source Projects Series" was launched to stop people interested in open source projects from being afraid and the sponsors of open source projects from being alone. Following our article, you will find the fun of programming, the use and the simplicity of participating in open source projects. Welcome to contact us to submit contributions, so that more people love open source, contribute to open source

Posted by aaaaCHoooo on Tue, 20 Aug 2019 01:08:04 -0700