07 - Mastering argparse
argparse introduction
- The string module has the variables: ascii_letters, digits, punctuation that are list of what they describe. This is quite handy.
- argparse.add_argument("-?", action=help)
- argparse.add_argument("-v", action=version)
- The
action=countstores the number of times the flag was written. E.g. -sss would store 3. action=extendis available starting from python3.8. It contrasts withappend.- nargs values
- * Zero or more
- ? Zero or one
-
- One or more
- An integer telling how many parameters to consume
- The choices parameter. The parameter can only take values present in a list.
- The
required=Truetells the parser that an optional parameter is actually mandatory. Best word here would be a keyword flag.
Mutually exclusive arguments
# starwars.py
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--light', action="store_true")
group.add_argument('--dark', action="store_true")
Allow abbreviation
By default, optional parameters are allowed to be passed in abbreviated form. That means any substring that matches the start of optional flag and it does not collides with any other start substring of other parameter. In the example above, all the below would work.
You can disable this feature with the argument allow_abbrev=False in the ArgumentParser constructor.
Read positional arguments from file
# add_person.py
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
parser.add_argument("name")
parser.add_argument("age")
Type
When you specify the type of the argument, the input will be passed to the call of what you specified in the type argument.
You can pass any callable.
parse.add_argument("character_code", type=ord)
parse.add_argument("file", type=open) # Not recommended
parse.add_argument("path", type=pathlib.Path)
Custom actions
# yoda.py
# The boolean optional action
parse.add_argument("--try", dest="Try", action=argparse.BooleanOptionalAction)
class BorkAction(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
if nargs is not None:
raise ValueError("nargs is not allowed for this custom action")
def __call__(self, parser, namespace, values, option_string=None):
result = values + " Bork, bork, bork!"
setattr(namespace, self.dest, result)
Alternatives to argparse
Exercise
- Not something to do now, but it should be an interesting exercise to implement an argparse. I guess that also reading and understanding the code of argparse could be also interesting.
- Read the document on the comparison between alternative parsers.