Background
Have you heard of the Singleton Pattern in Python? I encountered it while reading someone else’s code and didn’t understand what that piece of code meant. Later, when I searched for information, I learned that the purpose of that code is to create a single instance. It was from that moment that I became aware of the term “Singleton”, which is a design pattern in Python. In simple terms, it means that there is only one instance of a class object in memory.
Singleton Pattern Code
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
My Environment
import sys
print('Python version:', sys.version.split('|')[0])
# Python version: 3.11.11
Detailed Explanation with a Large Model
When the instance object is created for the first time, the class attribute <span>_instance = None</span> is set, and then the program enters the if condition to execute the key statement:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
# cls._instance = super().__new__(cls, *args, **kwargs)
1. <span>super(Singleton, cls)</span>‘s Role
- The super function: used to access methods from the parent class (base class), inheriting from the parent class and initializing it.
- Parameter meanings:
<span>Singleton:</span><span> the current class</span><span>cls:</span><span> a reference to the current class (in class methods, cls represents the class itself)</span>
This syntax explicitly specifies that the search for the parent class starts from the <span>Singleton</span> class in the MRO (Method Resolution Order). In Python 3, it can be simplified to <span>super()</span>, but this syntax more clearly shows the inheritance relationship.
2. <span>.__new__(cls, *args, **kwargs)</span>
- Calling the parent class’s
<strong><span>new</span></strong>method: this is the key step in actually creating the object instance.
super(Singleton, cls).__new__(cls) → actually calls object.__new__(Singleton)
In CPython (the official implementation of Python), <span>object.__new__</span> is a low-level function implemented in C. Its core tasks are:
- Memory allocation: allocating appropriate memory space for the new object.
- Object initialization: setting up the basic structure of the object.
- Returning the raw object: returning an “empty”, uninitialized object instance.
<span>object.__new__</span> is a low-level implementation that does not trigger the Python-level <span>__new__</span> method call. When <span>object.__new__</span> executes:
- It directly operates on memory allocation without going through Python’s method lookup mechanism.
- It is a built-in C function of the interpreter, not a Python function.
- Its job is to create the raw object without checking or calling any
<strong><span>new</span></strong>methods.
<span>object.__new__(Singleton)</span>‘s Working Principle:
- Memory allocation: allocating appropriate size memory for the Singleton instance.
- Object initialization: setting up the basic object header (type pointer, reference count, etc.).
- Returning the raw object: returning an “empty”, uninitialized object instance.
3. Return Assignment <span>cls._instance=</span> After step 2, the raw object will be assigned to <span>cls._instance</span>, which is actually the address/pointer of the class in memory. This way, the class attribute is no longer <span>None</span>, and if an instance is created again later, it will directly return the instance object created the first time.
Core Advantages of the Singleton Pattern
- Memory resource savings: there is only one object in memory, avoiding memory waste from creating duplicate instances.
- Reduced system overhead: the singleton can reside in memory for a long time, avoiding frequent creation and destruction of objects, thus reducing system overhead.
- Global access point: provides a global access point, allowing easy access to the unique instance in the application.
- Data synchronization control: with only one access point globally, better data synchronization control can be achieved, avoiding multiple occupancy.
Practical Application Scenarios of the Singleton Pattern
- Logger: applications usually only need one logger instance to avoid conflicts between multiple log files.
- Database connection pool: database connections are scarce resources, and using the singleton pattern can manage connections uniformly, avoiding resource waste.
- Configuration management: global configuration of applications usually only requires one instance to ensure consistency, such as initializing large models in memory/GPU only once to handle all user requests.
- Cache system: global caches need to be managed uniformly to avoid data inconsistency caused by multiple cache instances.
Related Historical Articles
- Detailed Explanation of Python Collections: Unlocking Efficient Data Structures
- Python Function Parameters: Lists as Default Values, a Hidden Trap!
- Two Useful Decorator Functions in Python
The above are some issues I encountered in practice, shared for everyone’s reference and learning. Feel free to follow the WeChat public account: DataShare, where I will share valuable content from time to time.