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.
- To create just one instance of a class, throughout the lifetime of a program.
Different ways to implement a Singleton:
A singleton pattern can be implemented in three different ways. They are as follows:
- Module-level Singleton
- Classic Singleton
- Borg Singleton
All modules are singleton, by definition. Let’s create a simple module-level singleton where the data is shared among other modules. Here we will create three python files – singleton.py, sample_module1.py, and sample_module2.py – in which the other sample modules share a variable from singleton.py.
## singleton.py shared_variable = "Shared Variable"
## samplemodule1.py import singleton print(singleton.shared_variable) singleton.shared_variable += "(modified by samplemodule1)"
##samplemodule2.py import singleton print(singleton.shared_variable)
Let’s look into the output.
Here, the value changed by samplemodule1 is also reflected in samplemodule2.
Classic Singleton creates an instance only if there is no instance created so far; otherwise, it will return the instance that is already created. Let’s take a look at the below code.
True Singleton Variable
Here, in the __new__ method, we will check whether an instance is created or not. If created, it will return the instance; otherwise, it will create a new instance. You can notice that singleton and new_singleton return the same instance and have the same variable.
Let’s check what happens when we subclass a singleton class.
True Singleton Variable
Here, you can see that SingletonChild has the same instance of SingletonClass and also shares the same state. But there are scenarios, where we need a different instance, but should share the same state. This state sharing can be achieved using Borg singleton.
Borg singleton is a design pattern in Python that allows state sharing for different instances. Let’s look into the following code.
False Shared Variable
Along with the new instance creation process, a shared state is also defined in the __new__ method. Here the shared state is retained using the shared_borg_state attribute and it is stored in the __dict__ dictionary of each instance.
If you want a different state, then you can reset the shared_borg_state attribute. Let’s see how to reset a shared state.
Here, we have reset the shared state and tried to access the shared_variable. Let’s see the error.
Traceback (most recent call last): File "/home/329d68500c5916767fbaf351710ebb13.py", line 16, in <module> print(newChildBorg.shared_variable) AttributeError: 'NewChildBorg' object has no attribute 'shared_variable'
Use cases of a Singleton:
Let’s list a few of the use cases of a singleton class. They are as follows:
- Managing a database connection
- Global point access to writing log messages
- File Manager
- Print spooler
Create a Web Crawler using Classic Singleton:
Let’s create a webcrawler that uses the benefit of a classic singleton. In this practical example, the crawler scans a webpage, fetch the links associated with the same website, and download all the images in it. Here, we have two main classes and two main functions.
- CrawlerSingleton: This class acts a classic singleton
- ParallelDownloader: This class provides thread functionality to download images
- navigate_site: This function crawls the website and fetches the links that belong to the same website. And, finally, it arranges the link to download images.
- download_images: This function crawls the page link and downloads the images.
Apart from the above classes and functions, we use two sets of libraries to parse the web page – BeautifulSoap and HTTP Client.
Have a look at the below code.
Note: Execute the code in your local machine
Let’s look into the downloaded images and python shell output.
Singleton pattern is a design pattern in Python that restricts the instantiation of a class to one object. It can limit concurrent access to a shared resource, and also it helps to create a global point of access for a resource.
Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.
To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course.