Why can't we just create static methods and attributes to use globally in our project? Using only class attributes without any object attributes also wouldn't be part of the singleton pattern, would there be any problem in using it this way? It's only for cases like unit tests where we need custom constructors? Example:
class GlobalInfo:
_global_data = {}
_lock = threading.Lock()
@staticmethod
def set_data(key, value):
with GlobalInfo._lock:
GlobalInfo._global_data[key] = value
@staticmethod
def get_data(key):
with GlobalInfo._lock:
return GlobalInfo._global_data.get(key)
I need something with singleton-like behavior to use in a project where more than one thread needs access to the same information. After reading a bit, I saw that people always override the __new__ method, etc. I would like to know if I really need to do that, and if not, for my specific case, would I be violating the singleton pattern?
No, there is no need to that in most cases, and you are right.
In some cases, however, the singleton needs to be initalized at runtime - maybe to make available in Python code the effect of some configuration parameter, or create some other process-wide resource.
In this case these recipes are valid - but not needed.
A pattern I like most, whenever I need a singleton like this (and usually, I prefer it than marking methods as static even if no initialization is needed), is to simply create an instance of the singleton class at module level - so that instance will be the object being imported and used through the project (and not its class).
Like in:
Followed by documenting that
MyConfshould be used.And if, for uniformity purposes, there is the need, or desire for the singleton to be called with the instance creation syntax, like proposed in the comment by @Barmar:
So - if that is desired, I simply include a
__call__method returningselfin the class:But I disagree with the reasoning that "the idea is to maintain it callable", however - Python's own builtin singletons like
None,TrueandFalsedo not need to be "instantiated", and they work very well. It may be a good fit in some places, though.Not that when dealing with static typing, the
__call__approach above won't work - in that case, the recipes using__new__might be a good approach, if one really wants the Singleton class to fake instantiation when it is to be used.