Singleton pattern
Overview
A Singleton is a design pattern that ensures a class creates only one object (an instance). If you ask for the object again, you get the exact same one. Imagine a family watching TV. There is only one TV remote. If the brother changes the volume, and the sister presses mute, they are pressing buttons on the exact same remote. A Singleton works the same way. It gives every part of your code the same shared object. Here is a simple Singleton using a module. In Python, files (modules) are natural Singletons. If you import a module twice, Python only creates it once. ```python # settings.py class MatchScoreboard: def __init__(self): self.score = 0 # We create the only instance right here. # We will import this specific instance in other files. board = MatchScoreboard() ``` Now we use it in different parts of our app: ```python # app.py from settings import board board.score = 50 print("Current score:", board.score) ``` If another file imports `board`, it sees the score as `50`. Let us practice. Here is a faded example. Fill in the blank to make `settings` a Singleton instance. ```python class DatabaseConfig: def __init__(self): self.port = 5432 # Fill the blank so other files can import 'config' ____ = DatabaseConfig() ``` The rule to remember: **A Singleton provides exactly one shared instance for the whole application.** This pattern is common for database connections, logging setups, or global settings. However, it has a trap. Because the state is shared, changing it in one file changes it everywhere. This can make bugs hard to find.
Sometimes creating multiple objects causes problems. For example, opening many connections to a database can crash it. A Singleton prevents this by reusing one connection.
Where used: Database connections, Configuration settings, Logging systems
Why learn this
- You will understand how Python modules share data.
- You will know how to manage global application settings safely.
Code walkthrough
class Config:
def __init__(self):
self.mode = 'test'
shared_config = Config()
shared_config.mode = 'production'
config_b = shared_config
print(config_b.mode)
Focus: config_b = shared_config
Aha moment
class UserData:
pass
user1 = UserData()
user2 = UserData()
print(user1 is user2)
Prediction: What does this print? True or False?
Common guess: True
By default, calling a class creates a BRAND NEW object every time. To get a Singleton, you must create the object once and share that specific instance, instead of calling the class again.
Common mistakes
- Unexpected shared state: Because a Singleton is shared, modifying a variable in one place affects the whole program. If a test changes the Singleton, the next test might fail.
- Hiding dependencies: If many functions use a Singleton hidden inside them, it is hard to know what data they need. It is often better to pass the data as an argument.
Recall questions
- Explain the Singleton pattern in your own words, as if to a classmate.
- Why would you use a Singleton instead of creating a new object every time?
- What is the simplest way to create a Singleton in Python without writing complex class logic?
Understanding checks
What does this code print?
light
The rule is: A Singleton provides exactly one shared instance. Both variables point to the same object. When file 1 changes the theme, file 2 sees the change.
A developer writes a game where three functions need to write to the same log file. Which pattern helps ensure they do not open three separate files?
The Singleton pattern.
A Singleton ensures only one logger object is created and shared, keeping the single file open safely.
Practice tasks
Use the shared instance
Given this code, modify `task_two` so it uses the exact same `system_cache` instance as `task_one`, instead of creating a new cache.
Continue learning
Previous: Class Creation and Instantiation