Python Singletons
In my opinion, good python libraries and frameworks should spend effort guiding you towards the ‘pit of success’, rather than trying to keep you from failing. They do this by spending most effort on things related to the critical path- clear interfaces, simple implementations, thorough documentation.
Which is why singletons are, to me, the worst form of framework masturbation in python. You will never be able to stop people from doing something stupid if they’re determined (in pure python). In the case of a singleton, that means instantiating more than one instance of a type. So spending effort on ‘designing’ singletons is not just a waste of effort, but actively harmful. Just provide a clear way to use a single instance, and your system should fail clearly if it detects an actual problem due to multiple instances (as opposed to, trying to detect multiple instances to keep said problem from happening).
The best method for singletons in python, then, is- whatever is simplest!
- Some form of module or class state is, to me, the clearest. It requires someone reading or using your code to know nothing more than the most basic python. Just prefix your class def with an underscore, and expose an accessor function to an instance stored on the module (or on the class). The capacity for failure is minimal and the behavior is clear (it requires no behavior modification to the type itself).
- Overriding __new__ is pretty bad but OK. It requires someone to understand the subtleties of __new__, which is a useful thing to teach someone but, are singletons really the time and place?
- Using a metaclass is a terrible solution. It has a higher likelihood of failure (how many people understand the nuances of metaclasses!?). Misdirection even for people just reading your code, trying to understand your type’s behavior. Avoid.
Hi
Python has support for singletons as good as it gets: modules
Before anything else that is what they are.
Yours Kay
@Kay Hayen
It would be strange to use a module as a singleton with many mutable members. And performance of module lookup is noticeable lower.
I gotta agree with Kay.
I use modules when I want a singleton.
However, I like the tone of the article.
If you really have to implement a singleton solution, make it a simple implementation.
That goes for every language.
I’ve seen tons of terrible versions in C++.
But any design in python that requires a singleton that I’ve been presented with could be solved with the module as object pattern.
I struggled with this a bit, coming from Java I suppose. I currently don’t have any cases multiple instances would cause harm, but they would be pointless. My answer is to design the class as I normally would then provide a module level instance as the default instance.
I do sometimes need a module level initialization function, if the class being used as a singleton requires some sort of configuration to be provided by the library user though.