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

【三】总结

相关推荐
童先生12 分钟前
Go 项目中实现类似 Java Shiro 的权限控制中间件?
开发语言·go
lulu_gh_yu13 分钟前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
Re.不晚37 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
老秦包你会39 分钟前
Qt第三课 ----------容器类控件
开发语言·qt
凤枭香42 分钟前
Python OpenCV 傅里叶变换
开发语言·图像处理·python·opencv
ULTRA??1 小时前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++
测试杂货铺1 小时前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
艾派森1 小时前
大数据分析案例-基于随机森林算法的智能手机价格预测模型
人工智能·python·随机森林·机器学习·数据挖掘
远望清一色1 小时前
基于MATLAB的实现垃圾分类Matlab源码
开发语言·matlab
confiself1 小时前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言