目录
什么是单例模式
能解决什么问题
使用场景
如何实现
__new__ 方法:经典又直接
装饰器:不改类本身,也能单例
模块本身就是单例
注意事项
总结
你有没有过这样的困扰:
“为什么我明明只创建了一次数据库连接,程序却悄悄多了好几个?资源占满了,性能还慢了。”
在软件世界里,有些东西,真的只需要一个就够了。这就是单例模式的世界。
什么是单例模式
单例模式(Singleton Pattern),本质上就是 保证某个类全局只有一个实例,无论你尝试创建多少次,得到的都是同一个对象。
形象一点:想象你家只有一台冰箱。无论家里多少人去开门、取东西,冰箱都是那一台,不会莫名其妙多出一个新冰箱。
能解决什么问题
- 统一管理资源:比如数据库连接,创建一次就够,避免重复占用资源
- 全局状态共享:日志记录器、配置文件、缓存对象…每个模块都能访问同一个实例
- 保证程序稳定性:避免多对象操作同一个资源导致混乱
简单说,单例模式让你的程序有序而高效,就像冰箱里的食物再多,也不会乱成一团。
使用场景
- 数据库连接:你不想每次操作都重新连接数据库
- 日志系统:程序里每个模块都能统一写入日志
- 配置管理:整个程序共享一个配置对象,方便修改与读取
- 缓存对象:统一存储数据,避免重复计算
换句话说,当“唯一性”是关键时,单例就登场了。
如何实现
__new__ 方法:经典又直接
class Singleton:_instance = Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance = super().__new__(cls)return cls._instancea = Singleton()
b = Singleton()
print(a is b) # True
- 核心理念:对象创建之前先检查“冰箱”是否存在
- 如果存在,就直接拿来用;不存在,才创建一个
装饰器:不改类本身,也能单例
def singleton(cls):instances = {}def wrapper(*args, **kwargs):if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return wrapper@singleton
class MyClass:passa = MyClass()
b = MyClass()
print(a is b) # True
- 想象:装饰器就像一个“守门员”,保证每个类的“冰箱”只出现一次
- 优点:无需修改类本身,易复用
模块本身就是单例
# singleton_module.py
class MySingleton:passinstance = MySingleton()
# main.py
from singleton_module import instancea = instance
b = instance
print(a is b) # True
- 特点:Python 模块天然单例
- 想象一下,模块就像整个城市的唯一冰箱,大家都能直接去用
注意事项
- 线程安全:多线程环境可能同时创建多个实例,需要加锁保护
- 不要滥用:单例是工具,不是全局变量的万能替代
- 继承问题:子类可能打破单例,需要特别处理
总结
单例模式就像 程序里的冰箱:
- 独一无二:全局只有一个实例
- 高效共享:避免重复资源浪费
- 有序管理:让全局状态清晰可控
下次当你遇到“必须保证唯一”的场景,想想冰箱,单例模式就自然而然地闪现在脑海里。