Python: thread-safe implementation of a singleton

Sometimes the singleton design pattern is required to limit resources usage like the number of connections to a database or an external API service.

In other languages this design pattern could be difficult to write I mean specifically to satisfy the thread safety but for Python it’s not really the case. Here is an easy implementation.

Implementation

 1import logging
 2import threading
 3
 4class MySingleton(object):
 5    _instance: object = None
 6    _lock: threading.Lock = threading.Lock()
 7
 8    def __new__(cls):
 9        """Create a new instance"""
10        if MySingleton._instance is None:
11            with MySingleton._lock:
12                if MySingleton._instance is None:
13                    MySingleton._instance = super(MySingleton, cls).__new__(cls)
14                    MySingleton._instance._initialized = False
15
16        return MySingleton._instance
17
18    def __init__(self):
19        """Initialize the instance"""
20        if self._initialized is False:
21            self._logger = logging.getLogger(self.__class__.__name__)
22            self._count = 0
23
24            self._initialized = True
25
26        self._logger.debug("using instance: %s" % self._instance)
27
28    def increment(self):
29        """Increment the counter"""
30        self._count += 1
31
32        self._logger.debug("count = %d" % self._count)

Test

To prove that it works let’s try in a python console:

>>> from code import MySingleton
>>> logging.basicConfig(level=logging.DEBUG, handlers=[logging.StreamHandler()])
>>> a = MySingleton()
DEBUG:MySingleton:using instance: <__main__.MySingleton object at 0x7f8bee80c550>
>>> b = MySingleton()
DEBUG:MySingleton:using instance: <__main__.MySingleton object at 0x7f8bee80c550>
>>> a.increment()
DEBUG:MySingleton:count = 1
>>> a.increment()
DEBUG:MySingleton:count = 2
>>> b.increment()
DEBUG:MySingleton:count = 3

As you can see the objects a and b share the same instance.