文章目录

  • 一、单例模式创建
    • 1.通过类方法创建
    • 2. 通过装饰器方法来创建
    • 3. 通过__new__方法来创建
    • 4. 通过模块创建
  • 二、多例模式创建

  单例模式与多例模式最主要的区别是:

单例模式是一个类只有单个对象被创建
多例模式是一个类可以有多个对象被创建

一、单例模式创建

下面展示单例模式的创建过程:

1.通过类方法创建

#!usr/bin/env python
# -*- coding:utf-8 -*-
"""
@author: admin
@file: 类方法.py
@time: 2021/05/24
@desc:
"""class Custom():def __init__(self, name):import timetime.sleep(1)self.name = name# 通过类方法创建实例@classmethoddef creat_class(cls, *args, **kwargs):# 如果没有对象if not hasattr(Custom, "_instance"):Custom._instance = Custom(*args, **kwargs)return Custom._instance# # 通过类方法来创建类的实例化对象
c1 = Custom.creat_class('张三')
c2 = Custom.creat_class('李四')
print(c1)
print(c2)
print(c1 is c2)  # True
<__main__.Custom object at 0x000002B8CD45F708>
<__main__.Custom object at 0x000002B8CD45F708>
True

但是,使用多线程时,使用类方法创建就会出现问题

#!usr/bin/env python
# -*- coding:utf-8 -*-
"""
@author: admin
@file: 类方法.py
@time: 2021/05/24
@desc:
"""
import threading
import timeclass Custom():def __init__(self, name):import timetime.sleep(1)self.name = name# 通过类方法创建实例@classmethoddef creat_class(cls, *args, **kwargs):# 如果没有对象if not hasattr(Custom, "_instance"):Custom._instance = Custom(*args, **kwargs)return Custom._instancedef task(arg):obj = Custom.creat_class('柳杰')print(obj)for i in range(10):t = threading.Thread(target=task,args=[i,])t.start()
<__main__.Custom object at 0x00000202CBD65148>
<__main__.Custom object at 0x00000202CBD62FC8>
<__main__.Custom object at 0x00000202CBD57048>
<__main__.Custom object at 0x00000202CBD62C08>
<__main__.Custom object at 0x00000202CBD62E88>
<__main__.Custom object at 0x00000202CBD62AC8>
<__main__.Custom object at 0x00000202CBD62988>
<__main__.Custom object at 0x00000202CBD62848>
<__main__.Custom object at 0x00000202CBD65288>
<__main__.Custom object at 0x00000202CBD62D48>

发现创建了不止一个对象!!!
解决办法:加锁!未加锁部分并发执行,加锁部分串行执行,速度降低,但是保证了数据安全

#!usr/bin/env python
# -*- coding:utf-8 -*-
"""
@author: admin
@file: 类方法.py
@time: 2021/05/24
@desc:
"""
import threading
import timeclass Custom():# 记录实例对象_instance_lock = threading.Lock()def __init__(self, name):import timetime.sleep(1)self.name = name# 通过类方法创建实例@classmethoddef creat_class(cls, *args, **kwargs):# 如果没有对象if not hasattr(Custom, "_instance"):with Custom._instance_lock:if not hasattr(Custom, "_instance"):Custom._instance = Custom(*args, **kwargs)return Custom._instancedef task(arg):obj = Custom.creat_class('柳杰')print(obj)for i in range(10):t = threading.Thread(target=task,args=[i,])t.start()time.sleep(20)
# 前面已经创建了对象,它就是单例模式
obj = Custom.creat_class()
print('------')
print(obj)
<__main__.custom object at 0x000001C79ABE3208>
<__main__.custom object at 0x000001C79ABE3208>
<__main__.custom object at 0x000001C79ABE3208>
<__main__.custom object at 0x000001C79ABE3208>
<__main__.custom object at 0x000001C79ABE3208>
<__main__.custom object at 0x000001C79ABE3208>
<__main__.custom object at 0x000001C79ABE3208>
<__main__.custom object at 0x000001C79ABE3208>
<__main__.custom object at 0x000001C79ABE3208>
<__main__.custom object at 0x000001C79ABE3208>
------
<__main__.custom object at 0x000001C79ABE3208>

2. 通过装饰器方法来创建

def wer(func):# 记录多个类的实例化对象_instance = {}def inner(*args, **kwargs):# 如果没有对象if func not in _instance:# 创建对象并将对象赋值给_instance_instance[func] = func(*args, **kwargs)return _instance[func]return inner@wer
class Myclass(object):passm1 = Myclass()
m2 = Myclass()
print(m1)
print(m2)print(m1 is m2)  # True
<__main__.Myclass object at 0x0000017483B89C08>
<__main__.Myclass object at 0x0000017483B89C08>
True

3. 通过__new__方法来创建

  当我们实现单例时,为了保证线程安全需要在内部加入锁。我们知道,当我们实例化一个对象时,是先执行了类的__new__方法实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,所有我们可以重写__new__方法,实现单例模式。

import threading
import timeclass Singleton(object):_instance_lock = threading.Lock()def __init__(self):time.sleep(1)def __new__(cls, *args, **kwargs):if not hasattr(Singleton, "_instance"):with Singleton._instance_lock:if not hasattr(Singleton, "_instance"):Singleton._instance = object.__new__(cls)return Singleton._instanceobj1 = Singleton()
obj2 = Singleton()
print(obj1, obj2)def task(arg):obj = Singleton()print(obj)for i in range(10):t = threading.Thread(target=task, args=[i, ])t.start()
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>
<__main__.Singleton object at 0x0000026593A073C8>

4. 通过模块创建

  Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

二、多例模式创建

## 平时我们使用的都是多例模式
class custom():passc1 = custom()
c2 = custom()
print(c1)
print(c2)
# 我们可以通过他们的内存地址来判断是否是同一个实例也可以使用is判断
print(c1 is c2)
<__main__.custom object at 0x0000020C6AC28408>
<__main__.custom object at 0x0000020C6AC5CF48>
False

参考:

  • 单例模式与多例模式
  • Python中的单例模式的几种实现方式的及优化

如果对您有帮助,麻烦点赞关注,这真的对我很重要!!!如果需要互关,请评论或者私信!


python—单例模式与多例模式的区别与创建相关推荐

  1. rethat安装MySQL多例_Spring框架-Bean作用域中单例模式和多例模式的区别

    Spring框架-Bean作用域中单例模式和多例模式的区别 一.单例模式的特点(当没有指定是单例模式还是多例模式的时候,默认是单例模式): 1.Spring容器创建的时候,对应的类的实例化对象一起被创 ...

  2. 单例模式和多例模式的区别(转)

    原文链接:[设计模式] 多例模式与单例模式区别 多例模式与单例模式都禁止外界直接将之实例化,同时通过静态工厂方法向外界提供循环使用的自身的实例.它们的不同在于单例模式仅有一个实例,而多例模式则可以有多 ...

  3. 多线程编程下单例模式与多例模式的使用总结

    最近研究了一下多线程在单例.多例下的使用,以及安全问题,总结如下: 1.先说一下什么是单例模式和多例模式. (1):单例模式:一个对象在内存中只有唯一个实例.它有两个主要的特点:构造函数私有,它的唯一 ...

  4. 单例模式和多例模式详解

    单例模式的关键有两点: 1.构造方法为私有,这样外界就不能随意调用. 2.get的方法为静态,由类直接调用 多例模式(Multiton) 1 .多例类可以有多个实例  2 .多例类必须能够自我创建并管 ...

  5. 什么是单例模式和多例模式

    单例模式的关键有两点: 1.构造方法为私有,这样外界就不能随意调用. 2.get的方法为静态,由类直接调用 多例模式(Multiton) 1 .多例类可以有多个实例 2 .多例类必须能够自我创建并管理 ...

  6. Spring——单例模式和多例模式

    singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例. prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new. ...

  7. python3 单例模式_当python,单例模式,多例模式,一次初始化遇到一起

    1.在python中,单例模式是很容易实现的,随便翻翻网上的相关教程,就能够找到很多答案. 比如这样: class hello(object): def __new__(cls, *args, **k ...

  8. Python设计模式:享元模式和单例模式

    设计模式八:享元模式和单例模式 什么是享元模式 享元模式是一个用于优化的设计模式,通过为相似对象引入数据共存来最小化内存使用,提升性能. 一个享元就是一个包含状态独立的不可变数据的对象,依赖状态的可变 ...

  9. 设计模式C#描述——单例与多例模式

    设计模式C#描述--单例与多例模式 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式有以下特点: 单例类只能有一个实例. 单例 ...

  10. 设计模式C#描述之——简单工厂模式、抽象工厂模式、单例与多例模式

    设计模式C#描述之--简单工厂模式 前 言:设计模式是软件开发领域的精髓之一.学好设计模式是目前每一个开发人员的必修课.目前关于设计模式的书很多,其中比较好的有GOF那本的中译本,但并 不很适合初学者 ...

最新文章

  1. SpringBoot使用笔记
  2. 精通Python网络爬虫:核心技术、框架与项目实战.1.1 初识网络爬虫
  3. android 分辨率合集,Android编程之分辨率处理相关代码段合集
  4. navicat 导入csv未响应_使用navicat将csv文件导入mysql
  5. Improved Alpha-Tested Magnification for Vector Textures and Special Effects
  6. Python3 内置http.client,urllib.request及三方库requests发送请求对比
  7. Py之pygame:有趣好玩—利用pygame库实现鱼儿自动实时目标跟踪(附完整代码)
  8. 连遭主流社交应用抛弃,是时候宣判黑莓系统死刑了
  9. ubuntu之apache正向代理及反向代理(ProxyPass\ProxyPassReverse)
  10. 松弛法(relaxation)
  11. 你说你会用Companion object?恐怕不是!
  12. 5G应用技术系列 - 从带宽和时延看5G和4G对应用区别
  13. No provider available from registry
  14. 网站外链如何才能被搜索引擎快速收录呢?
  15. 诺奖经济大师,数学天才赌徒,和“神秘的股市财富公式”
  16. python stdin.write_向stdin写入大量数据
  17. springboot+Vue开发的 ktv预定管理系统
  18. [python爬虫]爬取电影,电视剧
  19. mysql inet aton ipv6_在MySQL中存储IPv6地址
  20. twig  之基本语法

热门文章

  1. NFinal 控制器—URL
  2. 两列float引起的父容器高度失效的解决办法
  3. 复旦大学长跑协会申请书前言(初稿)
  4. java day31【web概念概述 、HTML】
  5. python-time、datetimme模块
  6. uva 1331 - Minimax Triangulation(dp)
  7. VC++的Unicode编程(经典之作,交流传薪)
  8. shift and算法
  9. ArrayList实现原理及源码分析之JDK8
  10. J2EE 快速开发框架 Wabacus 3.3 版功能列表