Global variables for python applications

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Wed May 19 10:34:37 EDT 2010


On Wed, 19 May 2010 00:16:56 -0700, TomF wrote:

> Let's say you have a bunch of globals, one of which is a verbose flag.
> If I understand the difference, using a module gbls.py: 
>
> # in gbls.py
> verbose = False
> # elsewhere:
> import gbls
> gbls.verbose = True
> 
> Using a class:
> 
> # In the main module:
> class gbls(object):
> 	def __init__(self, verbose=False):
> 		self.verbose = verbose
> 
> my_globals = gbls.gbls(verbose=True)
> ...
> some_function(my_globals, ...)
> 
> 
> If this is what you have in mind, I'm not really seeing how one is good
> practice and the other is bad.  The OOP method is more verbose (no pun
> intended) and I don't see how I'm any less likely to shoot myself in the
> foot with it.

Exactly! Both are considered harmful. Best is to avoid the use of globals 
if possible, not to disguise them by wrapping them in a class.

The second case (using a class) is slightly less harmful, because you can 
set up multiple global namespaces and do this:

some_function(my_globals, ...)
some_function(other_globals, ...)

which at least allows you to replace the globals on demand, but it is 
still somewhat of a code-smell. Best is to find a way of doing without 
them. (Note that global constants and functions are usually fine.)

Unfortunately, it's rarely possible to do entirely without global 
settings, except in trivial applications. But what you can do is use 
Python's dynamic programming to reduce the need to keep globals hanging 
around:


# Untested.
def verbose_print(arg, level, verbosity=1):
    if level <= verbosity:
        print arg

def my_function(arg):
    my_print(arg, level=2)
    return arg.upper()

if __name__ == '__main__':
    if '--verbose' in sys.argv:
        my_print = functools.partial(verbose_print, verbosity=2)
    elif '--quiet' in sys.argv:
        my_print = functools.partial(verbose_print, verbosity=0)

    my_function("hello world")        


Note that although there is no verbosity global setting, every function 
that calls my_print will do the right thing (unless I've got the test 
backwards...), and if a function needs to override the implicit verbosity 
setting, it can just call verbose_print directly.


-- 
Steven



More information about the Python-list mailing list