Modules are “singletons” in Python because import only creates a single copy of each module; subsequent imports of the same name keep returning the same module object.
A Singleton pattern in python is a design pattern that allows you to create just one instance of a class, throughout the lifetime of a program. Using a singleton pattern has many benefits. A few of them are: To limit concurrent access to a shared resource. To create a global point of access for a resource.
Creating a singleton decorator (aka an annotation) is an elegant way if you want to decorate (annotate) classes going forward. Then you just put @singleton before your class definition.
A common alternative to using a module as a singleton is Alex Martelli's Borg pattern:
class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
# and whatever else you want in your class -- that's all!
There can be multiple instances of this class, but they all share the same state.
Maybe you can put all the variables in a global dict, and you can directly use the dict in your functions without "global".
# Singleton-related variables
my_globals = {'foo': 'blah', 'bar':'stuff'}
# Functions that process the above variables
def work(some_parameter):
if some_parameter:
my_globals['bar'] = ...
else:
my_globals['foo'] = ...
why you can do it like this is Python Scopes and Namespaces.
One approach to implementing a singleton pattern with Python can also be:
have singleton __init()__
method raise an exception if an instance of the class already exists. More precisely, class has a member _single
. If this member is different from None
, exception is raised.
class Singleton:
__single = None
def __init__( self ):
if Singleton.__single:
raise Singleton.__single
Singleton.__single = self
It could be argued that handling the singleton instance creation with exceptions is not very clean also. We may hide implementation details with a method handle()
as in
def Handle( x = Singleton ):
try:
single = x()
except Singleton, s:
single = s
return single
this Handle()
method is very similar to what would be a C++ implementation of the Singleton pattern. We could have in Singleton
class the handle()
Singleton& Singleton::Handle() {
if( !psingle ) {
psingle = new Singleton;
}
return *psingle;
}
returning either a new Singleton
instance or a reference to the existing unique instance of class Singleton
.
Handling the whole hierarchy
If Single1
and Single2
classes derive from Singleton
, a single instance of Singleton
through one of the derived class exists. This can be verify with this:
>>> child = S2( 'singlething' )
>>> junior = Handle( S1)
>>> junior.name()
'singlething'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With