Propagate a default parameter of a function among several files I am starting to write a CLI using argparse library. This is my first attempt to structure a large project, usually I write single script. The CLI auto is defined in a top directory, helper functions are in a subfolder named project and a main function (where I want to put the logic of my program) in sub-sub-folder named sync.

Here is the tree-structure:


├── top/
├── auto
├── __init__.py
  └── project/
  ├── helper.py
  ├── __init__.py
    └── sync/
    ├── __init__.py
    ├── sync_file.py



helper.py:

def play(device, verbose=False):
    if verbose:
        print device + "with verbose on"
    else:
        print device + "verbose off"


sync_file.py:

from .. import helper

def main(device, verbose=False):
    helper.play(device,verbose)

if __name__ == '__main__':
    #Test here the logic        
    main('omv')
    main('omv',verbose=True)


auto:

#!/usr/bin/env python

import argparse
import project.sync.sync_file as logic_sync


def sync(args):
    if args.verbose:
        logic_sync.main(args.device,verbose=True)
    else:
        logic_sync.main(args.device)

parser = argparse.ArgumentParser(description='Info on my project')
subparsers = parser.add_subparsers()

sync_parser = subparsers.add_parser('sync', help='synchronize')
sync_parser.add_argument('--device', default='nas', help='specify the device name')
sync_parser.add_argument('--verbose', action='store_true', help='increase the output verbose')
sync_parser.set_defaults(func=sync)  # set the default function to sync


if __name__ == '__main__':
    args = parser.parse_args()
    args.func(args)


After I've made the auto file executable chmode +x auto I can use the CLI:

./auto sync
# nasverbose off
./auto sync --verbose
# naswith verbose on


I would like to keep this structure but I see a lot of repetition in propagating the verbose parameter from one file to another. Is there a better way to do it?
I would create a shared.py module somewhere (I'll let you handle the import directory tree). It would just contain

args = None

Import it in all your modules and assign args from argparser directly to it.
Now shared.args contains all the information (even device that you did not ask for :))

Of course this is not reentrant because of the shared global structure, but if you need reentrancy, you just have to pass 1 parameter: a fake args structure like argparse created (see the FakeArgs in syncfile.py)

And when you're ready to create one single python singleton object to avoid too much parameter passing, just yell :)

in auto code

#!/usr/bin/env python

import argparse
import shared
import project.sync.sync_file as logic_sync


def sync(args):
    shared.args = args
    logic_sync.main()

parser = argparse.ArgumentParser(description='Info on my project')
subparsers = parser.add_subparsers()

sync_parser = subparsers.add_parser('sync', help='synchronize')
sync_parser.add_argument('--device', default='nas', help='specify the device name')
sync_parser.add_argument('--verbose', action='store_true', help='increase the output verbose')
sync_parser.set_defaults(func=sync)  # set the default function to sync


if __name__ == '__main__':
    args = parser.parse_args()
    args.func(args)


sync_file.py code:

from .. import helper
import shared

def main():
    helper.play()

if __name__ == '__main__':
    #Test here the logic

    # we don't have argparse module creating the structure
    # for us ? what the heck? create a fake one

    class FakeArgs:
        def __init__(self):
           self.verbose = False
           self.device = 'omv'

    shared.args = FakeArgs()
    main()
    shared.args.verbose = True
    main()


helper.py code:

import shared
def play():
    if shared.args.verbose:
        print shared.args.device + " with verbose on"
    else:
        print shared.args.device + " verbose off"