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

【三】总结

相关推荐
dundunmm19 分钟前
机器学习之scikit-learn(简称 sklearn)
python·算法·机器学习·scikit-learn·sklearn·分类算法
古希腊掌管学习的神19 分钟前
[机器学习]sklearn入门指南(1)
人工智能·python·算法·机器学习·sklearn
波音彬要多做21 分钟前
41 stack类与queue类
开发语言·数据结构·c++·学习·算法
Swift社区29 分钟前
Excel 列名称转换问题 Swift 解答
开发语言·excel·swift
一道微光33 分钟前
Mac的M2芯片运行lightgbm报错,其他python包可用,x86_x64架构运行
开发语言·python·macos
矛取矛求37 分钟前
QT的前景与互联网岗位发展
开发语言·qt
Leventure_轩先生37 分钟前
[WASAPI]从Qt MultipleMedia来看WASAPI
开发语言·qt
向宇it1 小时前
【从零开始入门unity游戏开发之——unity篇01】unity6基础入门开篇——游戏引擎是什么、主流的游戏引擎、为什么选择Unity
开发语言·unity·c#·游戏引擎
四口鲸鱼爱吃盐1 小时前
Pytorch | 利用AI-FGTM针对CIFAR10上的ResNet分类器进行对抗攻击
人工智能·pytorch·python
是娜个二叉树!1 小时前
图像处理基础 | 格式转换.rgb转.jpg 灰度图 python
开发语言·python