Globals and singletons in Python
Question: I have some few classes which are widespread in my Python application and
which should have only one global instance (eg Logger, DbConnection). Python
does not support static variables/methods in a class, so the usual Java/C++
way to create a singleton here does not work. I have looked for alternatives
to implement singleton in Python. I want a simple (no metaprogramming if
possible) and clean implementation. This looks good:

    
    
    class MyClass(object):
        def a():
            pass
    
    singleton = MyClass()
    

Using the singleton would be simple as

    
    
    import myClass
    myClass.singleton.a()
    

The direct assignment could be replaced by a creation function if object
initialization is not so simple.

I could also create a getInstance() in module scope and always use it to get
myObj.

Question 1) This works ok? The module code (myObj assignment) only runs the
first time it is imported into some other module and myObj won't be created
every time I import this module somewhere?

An alternative method I have seen is to use a globals module. Something like:

    
    
    from myClass1 import MyClass1
    from myClass2 import MyClass2
    
    myObj1 = MyClass1()
    myObj2 = MyClass2()
    

Using this:

    
    
    import globals
    globals.myObj1.a()
    

I tend to prefer the first alternative.

Question 2) Between the 2 solutions, what do you recommend?

Question 3) A third solution would be passing the widespread objects such as
Logger to several classes/functions, but this is not a good solution imho. Is
there a better solution not mentioned here ?

I'm aware of the downsides of using global variables and singletons. However,
having a global state is not a big issue in my application. I'll prefer
solutions that have code clarity and are simple to use.


Answer: If you want to have a `logger` class that only has one instance, just make it
a separate module.

    
    
    # In logging.py
    def log(msg):
      print msg
    

Then from any script you want logging in.

    
    
    from logging import log
    log("A critical error occured.")
    

