NOTES
In this article, we are discussing the implementation of the Singleton Pattern in Python.
Use the link below to check the details of the Singleton Pattern-
Implementation
Method #1: Simple Implementation (Not recommended, demo purpose only)
WARNING
This is not the recommended way to implement Singleton in Python. We are showing it for learning purposes only.
Use the method described in the next section(Method #2: Using Metaclass) when you want to implement the Singleton pattern in Python.
from typing import Optional
class Singleton:
# Static variable to hold the singleton instance
_singleton_instance: Optional["Singleton"] = None
# Private constructor
def __init__(self, some_val: str) -> None:
if Singleton._singleton_instance is not None:
raise Exception("This class is a singleton!")
else:
self.some_val = some_val
@staticmethod
def get_instance(some_val: str) -> "Singleton":
# Check if the singleton instance is already created
if Singleton._singleton_instance is None:
Singleton._singleton_instance = Singleton(some_val)
return Singleton._singleton_instance
def print_details(self) -> None:
print(f"some val: {self.some_val}")
# Usage:
if __name__ == '__main__':
# Creating the first singleton instance
singleton_instance = Singleton.get_instance("abc")
singleton_instance.print_details()
# Trying to create another instance
another_instance = Singleton.get_instance("changed val")
another_instance.print_details()
# Uncommenting the following will raise an exception
# new_instance = Singleton("new value") # Error: This class is a singleton!
# Checking if both instances are the same
print(singleton_instance is another_instance)
PythonOutput:
Following output will be generated-
some val: abc
some val: abc
True
Method #2: Using Metaclass (Recommended way in Python)
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
# Create the singleton instance if it doesn't exist
instance = super().__call__(*args, **kwargs)
cls._instances[cls] = instance
return cls._instances[cls]
class Singleton(metaclass=SingletonMeta):
def __init__(self, some_val: str) -> None:
self.some_val = some_val
def print_details(self) -> None:
print(f"some val: {self.some_val}")
# Usage:
if __name__ == '__main__':
# Creating the first singleton instance
singleton_instance = Singleton("abc")
singleton_instance.print_details()
# Trying to create another instance
another_instance = Singleton("changed val")
another_instance.print_details()
# Checking if both instances are the same
print(singleton_instance is another_instance)
PythonNOTES
We could have used the _instances attribute to store a single object reference, instead of using a dictionary. But that would make it work for only one singleton class.
As we have used a dictionary, so we can use the same SingletonMeta class to implement the Singleton pattern for other classes. The _instances dictionary will store instances of all the all classes that are using SingletonMeta.
Output:
some val: abc
some val: abc
True
Examples
Example #1: Database Connection
DB Connection Singleton Class
Demo
Output
Following output is generated by the above code-
Creating new db connection instance
DB connection details for dbConnOne:
host:loclahost
port:1234
username:root
password:secret!pass
Using existing db connection instance
DB connection details for dbConnTwo:
host:loclahost
port:1234
username:root
password:secret!pass
PlaintextExample #2: Setting
Setting Singleton Class
Demo
Use the method “getInstance” to create a new instance of the setting class.
Output
array(2) {
["file_base_path"]=>
string(11) "/var/log/dd"
["app_port"]=>
int(3000)
}
array(2) {
["file_base_path"]=>
string(11) "/var/log/dd"
["app_port"]=>
int(3000)
}
PlaintextSource Code
Use the following link to get the source code:
Other Code Implementations
Use the following links to check Singleton pattern implementation in other programming languages.