4

I have a set (4 flags) of flags which control the nature of the output that my python script generates and ones which control how much information the script prints to the terminal (the way a verbose flag generally does). These flags are used by multiple functions. The values of the flags are set by optional command line arguments which I parse using argparse.

At present I have these flags in global scope outside of any of the functions that use the flags rather than have the flags passed as arguments to the functions. Like so:

import argparse
flag1=True
flag2=True
flag3=True

def fun1():
    ...
    if flag1:
        ..something..
    else: 
        ..something else..
    #fun1 also uses the other flags in a similar way
    ...

def fun2():
    ...
    if flag2:
        ..something..
    else: 
        ..something else..
    #fun1 also uses the other flags in a similar way
    ...

def main()
    ...
    args=parser.parse_args()
    ...
    global flag1
    flag1=args.flag1
    # and so on for the other flags 
    fun1()
    fun2()

I have been lead to believe that it is bad practice to use global variables in python from many of the answers here (this, for example). Does that apply here too? I am a little reluctant to pass the flags as arguments since I'll be passing too many variables as arguments.

What is the best way to handle flags set by command line arguments?

Community
  • 1
  • 1
Slothworks
  • 1,083
  • 14
  • 18

2 Answers2

2

The simplest solution would be to either pass all flags to all your functions (as a single args object) or pass relevant flags only depending on which function uses which flag.

Now this can indeed become quite of a burden, specially with nested function calls where you quickly end up having to pass the whole flags from function to function to function... The cure here is to use a class so you can share state between methods:

class Command(object):
    def __init__(self, flags):
        self.flags = flags

    def fun1(self):
        ...
        if self.flags.flag1:
            ..something..
        else: 
            ..something else..

    def fun2(self):
        ...
        if self.flags.flag2:
            ..something..
        else: 
            ..something else..


    def run(self):
        self.fun1()
        self.fun2()     

def main()
    ...
    args=parser.parse_args()
    cmd = Command(args)
    cmd.run()
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
0

I'm still a beginner, but keyword arguments seems a pretty good solution to your problem for me. I use something like this:

def foo(**kwargs):
    verbose = kwargs.get('verbose', 0)  # set default value for your options
    if verbose > 2:
       print >> sys.stderr, 'some debug message or sth like that'
    if verbose > 0:
       print 'verbose note'  # for sth like 'your_app -v'

if __name__=='__main__'
    args=parser.parse_args()
    verbose = args.flag1
    foo(verbose=verbose)
    foo()