乔克视界 乔克视界
首页
  • 运维
  • 开发
  • 监控
  • 安全
  • 随笔
  • Docker
  • Golang
  • Python
  • AIOps
  • DevOps
  • 心情杂货
  • 读书笔记
  • 面试
  • 实用技巧
  • 博客搭建
友链
关于
收藏
  • 分类
  • 标签
  • 归档

乔克

云原生爱好者
首页
  • 运维
  • 开发
  • 监控
  • 安全
  • 随笔
  • Docker
  • Golang
  • Python
  • AIOps
  • DevOps
  • 心情杂货
  • 读书笔记
  • 面试
  • 实用技巧
  • 博客搭建
友链
关于
收藏
  • 分类
  • 标签
  • 归档
  • Docker

  • Golang

  • AIOps

  • Python

    • 基础知识

      • Python之链表
      • Python 之类的初识
      • Python之函数式编程
      • Python之匿名函数
      • Python之自定义函数
      • Python之异常处理
      • Python之条件与循环
      • Python之列表生成式
      • Python之生成器
      • Python之装饰器
      • Python之迭代器
      • Python之进程、线程、协程
      • Python之深浅拷贝
      • Python之反射
      • Python之并发编程
      • Python之垃圾回收机制
      • Python之断言assert
      • Python之上下文管理器和with语句
      • Python中JSON的对应关系
      • Python之单例模式
        • 1、使用new方法
        • 2、通过函数装饰器
        • 3、通过类装饰器
        • 4、使用metaclass元类
        • 5、调用独有的实例对象
    • Django框架

    • 其他

  • DevOps

  • 专栏
  • Python
  • 基础知识
乔克
2025-07-19
目录

Python之单例模式

单例模式,即为一个类的实例从始至终只能被创建一次。

# 1、使用new方法

class Singleton(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance


class A(Singleton):
    def __init__(self, fruit):
        self.fruit = fruit


if __name__ == "__main__":
    banana = A('banana')
    apple = A('apple')
    print(id(banana) == id(apple))

# ----------------------
True
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

在 python 中,id()是用来查看对象在内存中的位置,如果其值相同,则代表其指向了同一个对象。

new()方法作用在init()之前,决定是否启用init()方法,通过new()方法将类的方法在创建时绑定到_instance,如果 cls._instance 为空,表示未被实例化,然后进行实例化操作,反之,表示已经被实例化,后面每次实例化都使用第一次实例化创建的实例。

# 2、通过函数装饰器

def singleton(cls):
    _instance = {}
    def inner():
        if cls not in _instance:
            _instance[cls] = cls()
        return _instance[cls]
    return inner


@singleton
class Singleton(object):
    def __init__(self):
        self.name = "ceshi"

a = Singleton()
b = Singleton()
print(id(a) == id(b))

# ----------------------------
True
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

这里使用_instance = {}来保存实例对象,每次都判断以下该类是否存在实例,如果存在就直接返回该实例,反之创建实例。

# 3、通过类装饰器

class Singleton(object):
    def __init__(self, cls):
        self.cls = cls
        self._instance = {}

    def __call__(self):
        if self.cls not in self._instance:
            self._instance[self.cls] = self.cls()
        return self._instance[self.cls]

@Singleton
class Test1(object):
    def __init__(self):
        self.name = "ceshi"

a = Test1()
b = Test1()
print(id(a) == id(b))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

道理和函数装饰器类似。

# 4、使用metaclass元类

class Singleton(type):
    def __init__(self, name, bases, class_dict):
        super(Singleton,self).__init__(name, bases, class_dict)
        self._instance = None
    def __call__(self, *args, **kwargs):
        if self._instance is None:
            self._instance = super(Singleton,self).__call__(*args, **kwargs)
        return self._instance
if __name__ == '__main__':
    class A(metaclass = Singleton):
        pass
    a = A()
    b = A()
    print(id(a) == id(b))
1
2
3
4
5
6
7
8
9
10
11
12
13
14

我们将类 A 的 metaclass 指向 Singleton,让 Singleton 中的 type 来创建 A 的实例。

# 5、调用独有的实例对象

# 定义一个模块sites.py
class Singleton(object):
    def __init__(self):
        print("这是一个被实例化的类")

singleton = Singleton()

# 然后在另外的模块中导入上面定义的模块test.py
from sites import singleton
1
2
3
4
5
6
7
8
9

只要程序启动,singleton 就是唯一的 Singleton()的实例化对象。

作者:乔克

本文链接:https://jokerbai.com

版权声明:本博客所有文章除特别声明外,均采用 署名-非商业性-相同方式共享 4.0 国际 (CC-BY-NC-SA-4.0) 许可协议。转载请注明出处!

上次更新: 2025/07/19, 11:33:23
Python中JSON的对应关系
Django之框架

← Python中JSON的对应关系 Django之框架→

最近更新
01
使用 Generic Webhook Trigger 触发 Jenkins 多分支流水线自动化构建
07-19
02
使用Zadig从0到1实现持续交付平台
07-19
03
基于Jira的运维发布平台
07-19
更多文章>
Theme by Vdoing | Copyright © 2019-2025 乔克 | MIT License | 渝ICP备20002153号 |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式