Python 面向对象之单例模式

【一】单例模式概念

  • 单例模式是一种设计模式,其核心思想是确保一个类只有一个实例,并提供一个全局访问点。
  • 单例模式通常用于管理共享的资源,例如配置信息、数据库连接、线程池等。
  • 关键点在于如何判断这个类是否已经实例化
    • 通过模块导入:借助模块的底层导入原理
    • 通过元类实现:元类的魔法方法__call__会在实例化之前执行,可以进行判断
    • 通过装饰器实现:装饰器也会在实例化之前操作,可以尽心判断

【二】单例模式实现方法

【1】通过模块导入

  • 这是最简单并且最好理解的方法,建议就用这个
python 复制代码
# module.py文件内容
class FuncTools(object):
    pass
func_tools = FuncTools()
python 复制代码
# 需要导入这个功能对象的文件
from module import func_tools
functools......
  • 模块只会导入一次,第二次导入时在内存中找到了这个实例对象,所以就不会再次生成一个新的实例

【2】通过元类实现

  • 有一点难度
python 复制代码
class MyMeta(type):
    __have_instance = None

    def __call__(cls, *args, **kwargs):
        if not cls.__have_instance:
            obj = super().__call__(*args, **kwargs)
            cls.__have_instance = obj
        return cls.__have_instance

class Student(metaclass=MyMeta):
    def __init__(self, name):
        self.name = name

student_one = Student("bruce")
print(student_one.name, id(student_one))
# bruce 2973012426224
student_two = Student("tom")
print(student_two.name, id(student_two))
# bruce 2973012426224
  • 在生成实例(student_one)的时候触发元类(MyMeta)的__call__方法进行判断没有实例,创建了实例
  • 在生成第二个实例(student_two)的时候再次触发元类(MyMeta)的__call__方法进行判断,有了实例直接返回已经存在,所以不会创建新的实例
  • 为什么是用的元类(MyMeta)的__call__方法呢?
    • 因为__init____new__都是在定义类(Student)的时候执行的
    • 仅执行了一次,并且还是在实例(student_one)之前触发的
    • 所以只能用元类(MyMeta)的__call__

【3】通过装饰器实现

  • 理解难度比元类好一点
python 复制代码
def singleton(cls):
    cls_dict = {}
    def inner(*args, **kwargs):
        if cls not in cls_dict.keys():
            cls_dict[cls] = cls(*args, **kwargs)
        return cls_dict[cls]
    return inner
@singleton
class Student(object):
    def __init__(self, name):
        self.name = name

student_one = Student("bruce")
print(student_one.name, id(student_one))
student_two = Student("tom")
print(student_two.name, id(student_two))
  • 通过装饰器singleton装饰类(Student
  • 在生成第一个学生(bruce)时,判断没有这个类没有产生实例,所以创建了实例(student_one
  • 在生成第二个学生(tom)时,判断这个类已经生成过实例,所以没有创建新的,返回第一次生成的实例(student_one

【三】总结

相关推荐
wxwx_bscxy32222 分钟前
基于Python新冠疫情可视化分析系统的设计与实现
java·数据库·spring boot·python·微信小程序·sqlite
TechWayfarer1 小时前
Cloudflare 9·15新政倒计时:用IP风险画像识别AI爬虫,防止误伤Googlebot
网络·人工智能·爬虫·python·tcp/ip·网络安全
禹凕1 小时前
滑动窗口算法实战指南
python·算法
论文复现现场2 小时前
RTX 4090 24GB 能跑 Qwen3.8-27B 吗?单卡显存计算与云端部署指南
人工智能·python·云计算·llama·gpu算力
Patrick在香港2 小时前
模型路由器实测:12 个任务省 77%,旗舰过载时的降级要打出显式标记
python·llm·智能路由器·api·架构设计·成本优化
Looooking2 小时前
Python 之 jwt 令牌生成和校验
python·jwt
天下无敌笨笨熊3 小时前
C#Modbus串口开发心得
开发语言·c#
电商API_180079052473 小时前
电商商品价格监控工具淘宝京东商品价格抓取API项目实操分享
java·大数据·开发语言·前端·数据挖掘
zzzll11113 小时前
深度剖析:HashMap 并发死循环与 ConcurrentHashMap 两代演进全解
java·开发语言
如意猴3 小时前
【C++】001--C++入门(1)
开发语言·c++