Explain Codes LogoExplain Codes Logo

Argparse optional positional arguments?

python
prompt-engineering
functions
best-practices
Anton ShumikhinbyAnton Shumikhin·Sep 28, 2024
TLDR

For an optional positional argument in argparse, use the nargs='?' parameter:

import argparse import os parser = argparse.ArgumentParser() parser.add_argument('directory', nargs='?', default=os.getcwd()) args = parser.parse_args() # Now args.directory holds current working directory by default if not provided. Neat huh?

Here, the directory argument is optional. If the user chooses not to specify a directory, args.directory defaults to the value of the current working directory.

Variety is the spice of life: Handling multiple directories

Craving more variety? Utilize nargs='*' for multiple optional directories. It collects zero or more arguments into a list:

parser.add_argument('directories', nargs='*', default=[]) args = parser.parse_args() # args.directories is a list of provided directories, or an empty party if none are provided

Deep diving into 'nargs'

The nargs parameter is a powerful tool that controls the number of command-line arguments to consume. Here's a cheat sheet:

  • '?': One argument or none, like a surprise party!
  • '*': Zero or more arguments, essentially a buffet
  • '+': At least one argument, no compromise!
  • argparse.REMAINDER: Every single remaining command-line arguments. No one gets left behind!

Parsing arguments and the Namespace object

After the arguments are defined, you use the .parse_args() method to convert command-line inputs into a Namespace object:

args = parser.parse_args()

Similar to a handy toolbox, this Namespace will carry attributes for each defined argument, holding provided values or the wary traveler's companions - the defaults.

Jack of all trades: Converting arguments into Paths

Consider converting arguments to Path types for a more flexible file or directory handling:

from pathlib import Path parser.add_argument('directory', nargs='?', type=Path, default=Path.cwd())

With this trick, args.directory is a Path object, pointing to the current working directory.

What action will you take: Using the 'action' parameter

The action parameter adds an extra flavor to how the command-line args are handled:

  • 'store_true': Perfect for boolean flags, it stores True if the flag is waved and False if not.
parser.add_argument('--verbose', action='store_true', help='Increase output verbosity (it won't really make it louder, don't worry)') args = parser.parse_args()

On using --verbose, args.verbose becomes True, much like you become happier when you eat your favorite dessert.

Keep things clean: Avoid errors and form clear help messages

Just a pro tip - Don't use required=False with positional arguments as it is not recognized in argparse. Instead, clearly describe optional arguments in the help message and let clarity prevail!

Going the extra mile with directories and files

When working with directories, defaulting to os.getcwd() is handy dandy. Applying Path from pathlib module can further simplify file/directory operations:

from pathlib import Path parser.add_argument('output_dir', nargs='?', type=Path, default=Path('/default/output/path'))

Now args.output_dir is a Path object pointing to /default/output/path by default. This is like storing your favorite snack in an easily accessible place!

No compromise: Forcing at least one argument

Sometimes, at least one value is non-negotiable, just like having at least one scoop of ice cream. The nargs='+' parameter enforces this:

parser.add_argument('input_files', nargs='+', help='List of input files')

Without any ice cream — ahem, I mean input_files — the parser will raise an error message that something sweet is missing.

Don't leave anyone behind: Handling remaining arguments

Maybe you need to account for an unspecified number of args after your known arguments. argparse.REMAINDER picks up the stragglers:

parser.add_argument('options', nargs=argparse.REMAINDER, help='Extra options on the side')

Every subsequent argument will join the party at args.options.

Ensure functionality with defaults

Having a default value for all optional arguments ensures that your script performs a basic jig even if users don't provide all the steps.