Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question

migrated from codereview.stackexchange.com Feb 11 at 19:46

This question came from our site for peer programmer code reviews.

    
Could you explain to me what the "true OO way" is and why there should be some compromise? –  User Feb 11 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 at 5:41
1  
Then this is an architectural question. Have a look at this: programmers.stackexchange.com/questions/252/… –  User Feb 12 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 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 at 22:56

1 Answer 1

up vote 2 down vote accepted

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.