首页 > 编程语言 >Python进阶之实现单例模式的常见方法

Python进阶之实现单例模式的常见方法

时间:2024-05-17 09:00:50浏览次数:14  
标签:__ 进阶 Python instance 实例 单例 id cls

【一】单例模式介绍

【1】什么是单例模式

  • 一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式

【2】为什么要学单例模式

  • 当一个类的功能比较单一,只需要一个实例对象就可以完成需求时,就可以使用单例模式来节省内存资源

【3】如何实现一个单例

  • 在python中,我们可以使用多种方法来实现单例模式
    • 使用模块
    • 使用装饰器
    • 使用类(方法)
    • 基于__new__方法实现
    • 基于元类metaclass实现

【二】类属性

  • 使用类属性保存实例,通过类方法获取实例。
  • 在第一次调用get_instance方法时创建实例,并在后续调用中直接返回该实例
  • 类产生对象
# 创建一个普通的类
class Student(object):
    pass


# 实例化类得到对象,类只要加()实例化就会产生一个全新的对象
stu1 = Student()
stu2 = Student()
print(id(stu1))  # 1711911837680
print(id(stu2))  # 1711911837680
# 两个对象的id不同
  • 类属性包装成方法
class Student(object):
    _instance = None

    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def get_instance(cls):
        if cls._instance is None:
            cls._instance = Student('ligo', 18)
        return cls._instance


stu1 = Student.get_instance()
stu2 = Student.get_instance()
print(id(stu1))  # 2387386923232
print(id(stu2))  # 2387386923232
# id 相同,是同一个实例

【三】装饰器

  • 使用装饰器将原来的类包装成一个新的类,通过闭包和字典保存实例。
  • 在每次实例化时,先检查字典中是否已经存在该类的实例,如果不存在才创建实例并返回
def outer(cls):
    instance = {}

    def inner(*args, **kwargs):
        if cls not in instance:
            instance[cls] = cls(*args, **kwargs)
        return instance[cls]

    return inner


@outer
class MyClass(object):
    pass


obj1 = MyClass()
obj2 = MyClass()

print(id(obj1))  # 2051247611504
print(id(obj2))  # 2051247611504

【四】元类

  • 定义一个元类,在元类的__call__方法中判断实例是否已存在,如果不存在则调用父类的__call__方法来创建并返回实例
class MyType(type):
    def __init__(cls, class_name, class_bases, class_dict):
        super(MyType, cls).__init__(class_name, class_bases, class_dict)
        cls.instance = None

    def __call__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super(MyType, cls).__call__(*args, **kwargs)
        return cls.instance


class MyClass(metaclass=MyType):
    pass


obj1 = MyClass()
obj2 = MyClass()

print(id(obj1))  # 2202077462144
print(id(obj2))  # 2202077462144
# id 相同,是同一个实例

【五】基于__new__方法

  • 在Python中,对象的实例化过程通常遵循以下步骤:
    • 首先执行类的__new__方法,如果未定义此方法,将默认调用父类的__new__方法来创建一个实例化对象,然后再执行__init__方法来对这个新创建的对象进行初始化
  • 利用实例化过程来实现单例模式:
    • 在类的__new__方法中判断是否已经存在实例,如果存在,则直接返回现有实例,否则创建一个新实例
    • 这样就能够确保只有一个实例存在,从而实现了单例模式的效果
class Student(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = super().__new__(cls)
        return cls._instance


stu1 = Student()
stu2 = Student()
print(id(stu1))  # 1711911837680
print(id(stu2))  # 1711911837680
# id相同,是同一个实例
# 重写__new__方法,在实例化对象时判断类中是否已有实例,如果没有则调用父类的__new__方法来创建并返回

【六】基于模块

class Student:
    pass


instance = Student()
# 将实例化操作放在模块级别,通过导入该模块来获取实例。
# 由于Python模块在运行时只会被导入一次,因此保证了实例的单一性

标签:__,进阶,Python,instance,实例,单例,id,cls
From: https://www.cnblogs.com/ligo6/p/18183507

相关文章

  • Python 类
    类的特殊方法call假设我们有一个类Calculator,它有一个__call__方法,用来计算两个数的和。代码如下:classCalculator:def__call__(self,a,b):returna+bcalc=Calculator()result=calc(3,5)print(result)在这个例子中,我们定义了一个Calculator类,其......
  • Python中解压一个包含中文文件名的ZIP文件到指定的目录
    要在Python中解压一个包含中文文件名的ZIP文件到指定的目录,你可以指定解压文件时所需的字符编码。下面是一个示例代码:importzipfileimportoszip_file_path='/path/to/your/chinese_file.zip'extract_dir='/path/to/extract/directory'#创建一个解压目标目录os.make......
  • python 逆向
    python逆向也是CTFreverse的一个重要组成部分(废话)。题目一般会给一个exe文件或者pyc文件。工具工欲善其事,必先利其器,好的工具是必不可少的。exe转pyc工具:GitHub-WithSecureLabs/python-exe-unpacker:AhelperscriptforunpackinganddecompilingEXEsco......
  • Python基础02
    Python基础02基础语法字面量掌握字面量的含义代码中,被写在代码中的固定的值,称之为字面量常见的字面量类型我们目前了解:整数、浮点数、字符串这三类即可如何基于print语句完成各类字面量的输出print(字面量),如:print(10),输出整数10print(13.14),输出浮点数13.......
  • python的一些常用编码技巧(持续更新)
    语法问题我常用的库函数1copy库importcopycopy.deepcopy()2、list库fromtypingimportList获取迭代对象的第一个值方法一:使用list方法my_dict={'a':1,'b':2,'c':3}first_key=list(my_dict.keys())[0]print(first_key)#输出:'a'方法二:使......
  • 数据结构简介及PYTHON里的数据类型
    1、什么是数据结构?先介绍几个概念。信息是目前在生活和工作中最经常听到的一个词,但要给信息这个概念一个容易理解的确切定义并不容易。人们希望用计算机处理的终极对象就是客观存在的各种信息,因此说计算机是处理信息的工具。数据是信息的载体,是指计算机(程序)能够处理的符号形式......
  • 电子书自由:python生成epub电子书
    前言最近在看《剑来》小说,但是kindle在线看不方便,而且我在网上找到的只有600多章,目前最新已经更新到了1200章,为了确保后面有书可读,同时也为了巩固下python技能,于是我找到一个免费的网站,然后通过python获取书籍内容,最终将获取到的内容,生成epub电子书,核心内容如下:获取电子书的内......
  • python部署至k8s解决方案
    前言最近做了一个全文检索的项目,项目之前的架子是别人搭建的,部署方式是docker-compose,到后期这个同事基本上不参与了,后面发布测试的时候,我们觉得这种方式不适合测试环境和线上发版(当然也可能是我们不熟悉,有点不专业了),于是就在他开发的基础上,做了一些调整:修改Dockerfile:把依赖打......
  • Python基础01
    Python基础01学习视频https://www.bilibili.com/video/BV1qW4y1a7fU软件pycharm通过快捷键快速设置字体大小常用快捷键ctrl+alt+s:打开软件设置ctrl+d:复制当前行代码shift+alt+上\下:将当前行代码上移或下移crtl+shift+f10:运行当前代......
  • 解决Python执行命令时路径空格引发的困扰
    哈喽,大家好,我是木头左!在编程实践中,常常需要通过Python执行系统命令,这包括调用外部程序、脚本或是其他命令行工具。然而,一个看似简单却常被忽视的细节——文件路径中的空格,可能会导致程序意外崩溃或行为异常。本篇文章将深入探讨当路径中包含空格时,如何在Python中正确执行命令,以......