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?
5
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.)