Skip to content Skip to sidebar Skip to footer

Python Argparse Set Behaviour When No Arguments Provided

I'm fairly new to python and I'm stuck on how to structure my simple script when using command line arguments. The purpose of the script is to automate some daily tasks in my job r

Solution 1:

You could append_const the funcs to an attribute, args.funcs, and then use one if-statement to supply the default behavior if no options are set:

if not args.funcs:
    args.funcs = [func1, func2, func3]

import argparse

deffunc1(): passdeffunc2(): passdeffunc3(): pass

parser = argparse.ArgumentParser()
parser.add_argument(
    "-l", "--list",
    dest='funcs', action="append_const", const=func1,
    help="Create CSV of images", )
parser.add_argument(
    "-i", "--interactive",
    dest='funcs', action="append_const", const=func2,
    help="Run script in interactive mode",)
parser.add_argument(
    "-d", "--dimensions",
    dest='funcs', action='append_const', const=func3,
    help="Copy images with incorrect dimensions to new directory")
args = parser.parse_args()
ifnot args.funcs:
    args.funcs = [func1, func2, func3]

for func in args.funcs:
    print(func.func_name)
    func()

% test.py
func1
func2
func3

% test.py -d
func3

% test.py -d -i
func3
func2

Note that, unlike your original code, this allows the user to control the order the functions are called:

% test.py -i -d
func2
func3

That may or may not be desireable.


In response to Update 2:

Your code will work just fine. However, here is another way you could organize it:

  • Instead of nesting the main program inside an if clause, you could use

    if not lists:
        sys.exit('No jpegs found')
    # put main program here, unnested

    sys.exit will print No jpegs found to stderr and terminate with exit code 1.

  • Although I originally suggested using functools.partial, another -- perhaps simpler -- way now comes to mind: Instead of

    forfuncinargs.funcs:func()

    we could say

    forfunc, argsinargs.funcs:func(args)

    All we need to do is store a tuple (func, args) in args.func instead of the function alone.

For example:

import argparse
import sys

def parse_args(lists):
    funcs = {
        'createCsv': (createCsv, lists['file_list']),
        'resizeImage': (resizeImage, lists['resized']),
        'optimiseImage': (optimiseImage, lists['size_issues']),
        'dimensionIssues': (dimensionIssues, lists['dim_issues']),
        'controlInput': (controlInput, lists)
    }
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-l", "--list",
        dest='funcs', action="append_const", const=funcs['createCsv'],
        help="Create CSV of images",)
    parser.add_argument(
        "-c", "--convert",
        dest='funcs', action="append_const", const=funcs['resizeImage'],
        help="Convert images from 1500 x 2000px to 900 x 1200px ",)
    parser.add_argument(
        "-o", "--optimise",
        dest='funcs', action="append_const", const=funcs['optimiseImage'],
        help="Optimise filesize for 900 x 1200px images",)
    parser.add_argument(
        "-d", "--dimensions",
        dest='funcs', action="append_const", const=funcs['dimensionIssues'],
        help="Copy images with incorrect dimensions to new directory",)
    parser.add_argument(
        "-i", "--interactive",
        dest='funcs', action="append_const", const=funcs['controlInput'],
        help="Run script in interactive mode",)
    args = parser.parse_args()
    if not args.funcs:
        args.funcs = [funcs[task] for task in
                      ('createCsv', 'resizeImage', 'optimiseImage', 'dimensionIssues')]
    return args

if __name__ == '__main__':
    lists = analyseImages()

    if not lists:
        sys.exit('No jpegs found')

    args = parse_args(lists)   
    statusTable(lists)    
    forfunc, argsinargs.funcs:func(args)

Solution 2:

You can handle this by checking if the number of args equals 1. meaning only your python command was passed.

import argparse
import sys

parser = argparse.ArgumentParser()
parser.add_argument("-l", "--list", help="Create CSV of images", action="store_true")
parser.add_argument("-d", "--dimensions", help="Copy images with incorrect dimensions to new directory", action="store_true")
parser.add_argument("-i", "--interactive", help="Run script in interactive mode", action="store_true")
args = parser.parse_args()

iflen(sys.argv)==1:
    # display help message when no args are passed.
    parser.print_help()
    sys.exit(1)

Solution 3:

Is that what you want?

if args.list:
    func1()
if args.interactive:
    func2()
if args.dimensions:
    func3()
if not any(vars(args).values()):
    func1()
    func2()
    func3()

(Thanks @J.F.Sebastian for the any version)

Post a Comment for "Python Argparse Set Behaviour When No Arguments Provided"