单例模式《单例模式概念、什么时候能用到单例模式、单例模式的好处》
坚持原创输出,点击蓝字关注我吧
作者:清菡
博客:oschina、云+社区、知乎等各大平台都有。
目录
一、单例模式的概念
1.类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎么做呢?
二、什么时候能用到单例模式?
三、单例模式的好处
1.单例模式好处
2.代码目录结构
一、单例模式的概念
1.类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎么做呢?
__new__
方法是用来创建实例对象的,通过类去创建方法的时候,实际上类自动调用的__new__
方法。
调用完__new__
方法,创建好对象之后,再把对象交给__init__
做一个初始化的设置。
创建一个对象的时候,我们自己不需要调用,我们的这个类自动调用这2个方法。这2个方法叫做魔术方法(因为它们是双下划线开头,双下划线结尾的)。
这个__new__
方法:
def __new__(cls.*args,**kwargs):print('-----new方法-----')return object.__new__(cls)
刚才重写之后,感觉重写这个东西还要调用父类的__new__
方法,然后将它的结果进行返回,好像没有什么作用。
图片来自网络
单例模式: 就是我们创建一个类,这个类只能被实例化一次,也就是说这个类只能创建出来一个实例对象,这种叫做单例模式。
二、什么时候能用到单例模式?
比如你当前写了个小系统,在系统里有些相关的配置(是整个系统通用的配置),如果把这所有的配置都放在一个类里面存储,这个时候,在程序的任何地方用到的配置都是一样的。
这个时候,用到的时候,创建一个类,给里面添加一些配置。要修改的时候,再创建一个类,然后添加一些同样的配置,这个时候就是浪费资源。
三、单例模式的好处
1.单例模式好处
不管你实例化多少次,它始终只返回第一次创建的对象。不管你什么时候创建,它始终返回这一个对象。
比如在这个qh_05day_01.py里面实现了一个单例模式:
# 1、多个装饰器装饰同一个函数# 2、python中类里面三个内置的装饰器# 3、用类实现装饰器
import time
def wrapper(func):def count_time(*args,**kwargs):print("计算时间的装饰器")start_time=time.time()func(*args,**kwargs)end_time=time.time()print("函数运行的时间为:{:.5f}".format(end_time-start_time))return count_timewith open("zy/user.txt") as f:users=eval(f.read())def login_check(func):def ado(*args,**kwargs):print("登录校验的装饰器")if not users["token"]:print("-----登录页面-------")username=input("账号:")password=input("密码:")if users["user"] == username and users["pwd"] == password:users["token"] =Truefunc(*args,**kwargs)else:func()return ado@login_check # 第二步进行装饰 count_time---->func=login_check(func) func指向的是ado这个函数
@wrapper # 第一步进行装饰 func=wrapper(func) func指向的是count_time这个函数。
def func():time.sleep(3)print("这是是需要被装饰器的函数")
# 从下往上装饰,从上往下执行
func()class MyTest(object):def __init__(self,name):#设置一个初始化属性叫做nameself.name = name@classmethod # 被classmethod装饰了之后,该方法就是一个类方法def add(cls):# cls 代表的是类本身print("add")print(cls)@staticmethod # 静态方法 实例和类都可以调用def static():print("这个是静态方法")@property # 设定只读属性def read_attr(self):print("这个装饰器装饰完了之后,该方法可以像属性一样被调用")return "20岁"def sub(self):# self 代表的是实例本身print("sub中的self",self)# MyTest.static() #类调用#
# t= MyTest("qinghan")
# 通过name可以访问到这个属性,可以对这个属性进行更改
# t.name="lily"
# print(t.name)
# t.read_attr="19岁"
# print(t.read_attr)
# t.static()#实例调用
# t.add()
# t.sub()
给它创建了一个对象,给它添加好了一些配置。
在qh_05day_02.py里没有用到:
class MyClass(object):def __init__(self,name):self.name=nameprint("__init__方法调用了")
# 重写下__new__方法def __new__(cls, *args, **kwargs):print("这个是new方法")# 子类里调用下父类的方法,并进行返回return object.__new__(cls)m = MyClass("qinghan")
# print(m.name)
# print(m)
在这里要把实例对象倒过来。
忘记创建的实例对象叫做什么名字了,记住它的类名就行了。找到定义单例模式的那个类,把那个类倒进来。
这里再创建一个对象,那么这个对象还是原来那边创建好的对象。原来设置好的属性,这里也全部都有,不需要再全部添加。
在这里通过Mytest
创建出来一个对象。
把qh_05day_01.py中代码修改成这样:
# 1、多个装饰器装饰同一个函数# 2、python中类里面三个内置的装饰器# 3、用类实现装饰器
import time
def wrapper(func):def count_time(*args,**kwargs):print("计算时间的装饰器")start_time=time.time()func(*args,**kwargs)end_time=time.time()print("函数运行的时间为:{:.5f}".format(end_time-start_time))return count_timewith open("../class_03day/zy/user.txt") as f:users=eval(f.read())def login_check(func):def ado(*args,**kwargs):print("登录校验的装饰器")if not users["token"]:print("-----登录页面-------")username=input("账号:")password=input("密码:")if users["user"] == username and users["pwd"] == password:users["token"] =Truefunc(*args,**kwargs)else:func()return ado@login_check # 第二步进行装饰 count_time---->func=login_check(func) func指向的是ado这个函数
@wrapper # 第一步进行装饰 func=wrapper(func) func指向的是count_time这个函数。
def func():time.sleep(3)print("这是是需要被装饰器的函数")
# 从下往上装饰,从上往下执行
func()class MyTest(object):def __init__(self):#设置一个初始化属性叫做namepass@classmethod # 被classmethod装饰了之后,该方法就是一个类方法def add(cls):# cls 代表的是类本身print("add")print(cls)@staticmethod # 静态方法 实例和类都可以调用def static():print("这个是静态方法")@property # 设定只读属性def read_attr(self):print("这个装饰器装饰完了之后,该方法可以像属性一样被调用")return "20岁"def sub(self):# self 代表的是实例本身print("sub中的self",self)MyTest.static() #类调用# t= MyTest("qinghan")
t= MyTest()# 通过name可以访问到这个属性,可以对这个属性进行更改
t.name="lily"
# print(t.name)
# t.read_attr="19岁"
print(t.read_attr)
# t.static()#实例调用
# t.add()
# t.sub()
去掉一个name属性。
文件qh_05day_02.py
from qh_05day.qh_05day_01 import MyTest
t1=MyTest()class MyClass(object):def __init__(self,name):self.name=nameprint("__init__方法调用了")
# 重写下__new__方法def __new__(cls, *args, **kwargs):print("这个是new方法")# 子类里调用下父类的方法,并进行返回return object.__new__(cls)m = MyClass("qinghan")
# print(m.name)
# print(m)
t1对象会拥有t对象拥有的属性。
t对象,在这里你给它设置了什么属性。在t1对象那里都有,不需要重新设置了。
通过MyTest这个类去创建的时候,始终只会返回一个实例。不管你用这个类去创建实例多少次,最终给你返回的始终只有一个对象。就是它第一次创建的那个对象。
这个类只能实例化一次,只能创建一个实例化对象。
不管你创建多少次,只能一个。
2.代码目录结构
打开文件,我的本地路径是:C:\Users\18210\Desktop\所有文件\python\python_ck01\qh_05day
清菡软件测试,腾讯云年度最佳作者,非著名软件测试工程师。
文章中的图片,除标明 图片来自网络 的图片,其它图片皆为清菡本人所画。计算机知识都一样,文章是清菡的笔记。如有雷同,纯属巧合。
公众号 清菡软件测试 首发,更多原创文章:清菡软件测试 134+原创文章,欢迎关注、交流,禁止第三方擅自转载。如有转载,请标明出处。
单例模式《单例模式概念、什么时候能用到单例模式、单例模式的好处》相关推荐
- 设计模式6---(单例模式的概念及其实现(懒汉式和饿汉式),线程安全)
单例模式 单例模式的概念 单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象.也就是说,在整个程序空间中,该类只存在一个实例对象. GoF 对单例模式的定义是:保证一个类 ...
- 单例模式应用场景_【简易设计模式04】单例模式
总第56篇 在上篇中,我们对整个系统的设计应遵循的六大设计原则进行了系统性的梳理和讲解.在开发过程中,我们应尽量按照这些设计原则去做,当然也不能生搬硬套,要适当权衡,根据自己的项目情况.项目场景去考量 ...
- android单例模式代码,设计模式(一):Android 源码中的单例模式
设计模式(一):Android 源码中的单例模式 2020-08-17 22:51 阅读数 57 <>什么是单例模式? 单例模式(Singleton) 是最常见也最简单的设计模式,它的目的 ...
- Java23种设计模式之单例模式的五种实现方式、反射破解单例模式、不能破解枚举单例模式详解
源码链接(Gitee码云):https://gitee.com/oldou/javadesignpatterns 这里有我整理好的Java23种设计模式的源码以及博客教程,博客教程中介绍了Java23 ...
- 大话设计模式之爱你一万年:第二章 创建型模式:单例模式:我的女朋友只有你一个:1.单例模式的基本概念
1.单例模式的基本概念 我的女朋友总是你喜欢问:我在你心中是不是唯一的存在? 我:在我心里你就是独立无二的,谁都不能替代. 女朋友:那你证明一下. 我:Talk is cheap
- python实现单例模式的几种方式_基于Python中单例模式的几种实现方式及优化详解...
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- 单例模式应用场景_面试:请你谈谈单例模式的优缺点,注意事项,使用场景
单例模式介绍: 单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对象的类必须保证只有一个实例存在.许多时候整个系统只需要拥有一个全局对象,这样有利于我们协 ...
- 大话设计模式之爱你一万年:第二章 创建型模式:单例模式:我的女朋友只有你一个:2.单例模式的实现-懒汉模式
2.单例模式的实现-懒汉模式 视频学习地址 -- <大话设计模式之爱你一万年>:https://dwz.cn/wqO0MAy7 这一节我们先来看看一种实现模式,懒汉模式,这也是这么中实现 ...
- java单例模式的实现方法_Java中的五种单例模式实现方法
Ext4 ComboBox组件使用 先来看例子: Ext.define('schoolModel', { extend: 'Ext.data.Model', fields: [{ name: 'id' ...
最新文章
- Python取出列表相应值的位置(表处理)
- 文档信息的向量化-词袋模型、gensim实现和词条分布
- mysql int和bigdecimal,mysql的 int 类型,刨析返回类型为BigDicemal 类型的奇怪现象
- 2月书讯 | 冬奥结束看什么?看看“天花板”级别新作!
- 甘肃宕昌山货“触网”外销:山民乐衷创业“等客来”
- 开发日记-20190819 关键词 随便聊聊
- 删除已使用过且无法删除的替代
- numpy添加元素_科研速递 | 花费15年众望所归!NumPy论文终登上Nature!
- MySQL使用distinct去掉查询结果重复的记录
- matlab for 取数组,for循环中的MATLAB和单元格数组处理
- The requested URL was not found on the server
- 使用AWS Lambda的CloudWatch事件通知
- php 获取每年的节假日,shell获取每年农历节日的日期
- 【BAT面试现场】如何判断一个数是否在40亿个整数中?
- UVA1583 UVALive3355 Digit Generator
- 互金累计融资近千例 借贷行业融资数量居首位
- java实现-现奔跑吧小恐龙-小游戏
- 用python把微信好友头像拼成一张图
- SqlServer遇到以零作除数错误
- Python编程:通过百度地图接口抓取机构的地址和电话信息