6

Ok, I know that using singletons is generally a bad practice, but if I do it (for db connection, logging et al.) am I allowed to go (in respect of clean design) with a module defined variable that is initialized during the startup.

eg.:

if __name__ == '__main__':
    datasources.database.db = DB(dbpath)

where db is declared here, at the top level of a module:

db = None

class DB(object):
    def __init__(self, path):
         ....

What could be a reasonable compromise between passing the db for each object that uses it in the "true OO way" and having the global?

zeller
  • 161
  • 1
  • 6
  • Could you explain to me what the "true OO way" is and why there should be some compromise? – User Feb 11 '14 at 21:39
  • @User Let's say that the true oo way is that you pass the things your types use as arguments instead of accessing them globally. But what I really wanted to ask is that is it ok to do use this kind of globals in python, or it's a code smell. – zeller Feb 12 '14 at 05:41
  • 1
    Then this is an architectural question. Have a look at this: http://programmers.stackexchange.com/questions/252/when-is-singleton-appropriate?rq=1 – User Feb 12 '14 at 14:23
  • @User thanks for the link, actually with this in my mind asked that what python masters think about global singletons. Maybe this is the wrong forum to ask such questions... – zeller Feb 12 '14 at 14:42
  • I think that this is the best way to implement a Python singleton, yes. Whether you should use a singleton at all is a different question and, imho, off topic. – user16764 Feb 18 '14 at 22:56

1 Answers1

3

The issue with global singletons comes down to code maintenance, architecture, and thread-safety.

In python, unless you're using Stackless Python, the GIL(Global Interpreter Lock: https://wiki.python.org/moin/GlobalInterpreterLock) does help guarantee thread-consistency (as opposed to safety), so this is less of an issue in Python than other languages.

However, what you need to ask when you're looking at singletons is why?

What can a global singleton give you that a static method or class or cache can't? What about using a Factory design pattern to properly handle creating DB resources?

The problem with a singleton in use is that an object being a singleton is non-obvious, while static classes or methods or caches are much more obvious in how they can be used and interacted with.

Consider the following issue:

You decide to use a singleton in a library. Six months later, you find a user story where you need multiples of that singleton - but you've forgotten its a singleton. You try and create copies, instantiate new ones, etc etc and keep running into all these weird defects.

This is where singletons become a code maintenance issue, and until you've suffered the costs and frustrations brought about by this, its hard to understand why singletons are such a big code smell issue.

Imagine even worse, that you don't have the source code for the library, the documentation has been lost, and you didn't write it. How would you know a returned object was a singleton?

(I have experienced the above at a job previously... that was... fun for certain definitions of fun.)

Zeroth
  • 533
  • 2
  • 13