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

【三】总结

相关推荐
hqxstudying6 分钟前
JAVA项目中邮件发送功能
java·开发语言·python·邮件
咪咪渝粮9 分钟前
JavaScript 中constructor 属性的指向异常问题
开发语言·javascript
最初的↘那颗心9 分钟前
Java HashMap深度解析:原理、实现与最佳实践
java·开发语言·面试·hashmap·八股文
Q_Q51100828524 分钟前
python的软件工程与项目管理课程组学习系统
spring boot·python·django·flask·node.js·php·软件工程
合作小小程序员小小店1 小时前
SDN安全开发环境中常见的框架,工具,第三方库,mininet常见指令介绍
python·安全·生成对抗网络·网络安全·网络攻击模型
后台开发者Ethan1 小时前
Python需要了解的一些知识
开发语言·人工智能·python
北京_宏哥1 小时前
Python零基础从入门到精通详细教程11 - python数据类型之数字(Number)-浮点型(float)详解
前端·python·面试
盼小辉丶2 小时前
PyTorch生成式人工智能——使用MusicGen生成音乐
pytorch·python·深度学习·生成模型
常利兵2 小时前
Kotlin作用域函数全解:run/with/apply/let/also与this/it的魔法对决
android·开发语言·kotlin
幼稚园的山代王2 小时前
Kotlin-基础语法练习一
android·开发语言·kotlin