
文章目录
一、单例模式解释
二、Python中的单例实现
三、单例模式的“翻车现场”
四、适用场景
单例模式的核心思想:无论程序如何调用,类都只能存在一个实例,并且所有人都得共享这个实例 。
# emperor.py
class Emperor:
def __init__(self):
self.gold = 1000000
emperor = Emperor() # 模块加载时自动创建实例
其他文件直接导入这个模块即可:
from emperor import emperor
emperor.gold -= 1 # 对所有的导入都生效
__new__魔法控制实例化
如果你想玩点高级操作,可以通过重写__new__方法,手动控制实例的创建:class Emperor:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.gold = 1000000
return cls._instance
# 测试一下
e1 = Emperor()
e2 = Emperor()
print(e1 is e2) # 输出:True!e1和e2是 同一个 对象
实例化的时候,如果 cls._instance 不为 None 就直接返回已有的实例
这种方法更灵活,但要注意线程安全问题
Python默认使用内置的type作为元类来创建类。当定义一个类时,Python会通过type元类自动处理类的属性和方法。如果需要自定义类的创建逻辑(比如动态修改类属性、强制约束类结构、自动注册子类等),就可以通过自定义元类实现,通过重写__new__、__init__ or __call__方法来实现
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Emperor(metaclass=SingletonMeta):
def __init__(self):
self.gold = 1000000
# 无论怎么创建,都是同一个
e1 = Emperor()
e2 = Emperor()
e3 = Emperor()
e1.gold = 0
print(e2.gold) # 输出:0
print(e3.gold) # 输出:0
这种方法优雅且通用
虽然单例模式很香,但也要小心“踩坑”:
单例模式的使用场景主要集中在需要确保全局唯一实例或高效共享资源的场合
总结来看,单例模式的核心价值在于减少资源消耗、确保全局唯一性,但需注意其潜在缺点(如全局状态滥用可能导致代码耦合度高)。