Python基础7——单例模式

15 单例模式

15.1 init和new方法

执行步骤

  1. 实例化一个对象,先执行new方法,在new方法中返回对象
  2. 然后再调用init方法

15.1.1 __init__方法

__init__ 是构造方法

<font color="red">其实最先调用的方法是new方法</font>,但是大部分情况下是不使用new方法

1class Test(object): 2 def __init__(self): 3 print("这是init方法") 4 5t = Test()

15.1.2 __new__方法

__new__

步骤:实例化对象时,python解释器会先调用new方法为对象分配空间,然后再执行init初始化对象

new方法的作用

  1. 在内存中为对象分配空间

  2. 返回对象的引用

python解释器获取对象的引用后,将引用作为第一个参数,传递给init方法

1 2class Person(object): 3 def __init__(self): 4 print("这是init方法") 5 6 def __new__(cls,*args,**kwargs): #cls代表类对象本身 7 print("这是new方法",cls) 8 9 10p = Person() 11print(pe) 12# 运行结果 13# 这是new方法 <class '__main__.Person'> 14# None 15 16注意!!!:并没有执行init方法

第一种写法

1# 重写new方法 2class Person(object): # object提供的new方法 3 def __init__(self): 4 print("init") 5 6 def __new__(cls,*args,**kwargs):#cls表示这个类 7 print("new") # 先执行new方法的代码 8 res = object.__new__(cls) #调用父类的new方法 9 print(res) #res就是实例化后的对象的引用 10 return res #将实例后的结果进行返回 11 12p2 = Person() 13 14# 输出结果 15# new 16# <__main__.Person object at 0x000001C67F368A48> 17# init

第二种写法

1# 重写new方法 2class Person(object): # object提供的new方法 3 def __init__(self): 4 print("init") 5 6 def __new__(cls,*args,**kwargs):#cls表示这个类 7 print("new") # 先执行new方法的代码 8 return super().__new__(cls) 9 10p2 = Person() 11 12# 输出结果 13# new 14# <__main__.Person object at 0x000001C67F368A48> 15# init

**init方法时什么时候被自动调用? **

​ 实例化的时候调用

**new方法是用来创建实例对象,new方法是从哪里来的? **

​ object这个类出来的

**self里面是什么? **

​ self代表实例对象本身

15.2 单例模式的介绍

单例模式:是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中系统中,某个类只能出现一个实例

实现单例模式的方法

  1. 通过@classmethod
  2. 通过装饰器实现
  3. 通过__new__实现 (重点)
  4. 通过导入模块实现

单例模式设计流程

  1. 定义一个类属性,初始值为None,用于记录单例对象的引用
  2. 重写new方法
  3. 进行判断,如果类属性是None,则new方法返回的对象引用保存进去。
  4. 返回类属性中记录的对象引用

15.3 使用__new__方法实现单例模式

1# 无论实例化多少次,都实例化一个实例 2 3class Exam(object): 4 # 记录第一个被创建的对象引用 5 ins = None #类属性 6 7 def __init__(self): 8 print("init方法") 9 10 def __new__(cls,*agrs,**kwargs): 11 12 if cls.ins is None: #如果为空,则创建一个 13 cls.ins = object.__new__(cls) 14 15 return cls.ins #返回唯一的实例对象 16 17a = Exam() 18print(a) 19a2 = Exam() 20print(a2) 21

15.4 通过装饰器的方式实现单例模式

通过装饰器的方法来实现

1class Exam(object): 2 ins = None 3 4 5def outer(fn): #被修饰的类名 6 # 创建一个字典来保存类的实例对象 7 ins_dict = {} #{类名:实例,类名2:实例2} 8 9 def inner(): 10 if fn not in ins_dict: #如果字典中没有对象 11 # 创建一个对象,保存在字典中 12 res = fn() #实例化一个对象 13 ins_dict[fn] = res #添加信息 14 return ins_dict[fn] 15 return inner 16 17@outer 18class Animal(object): #单例模式的类 19 pass 20 21t1 = Animal() 22print(t1) 23t2 = Animal() 24print(t2) 25 26
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

Python中的__new__及其用法

\_\_new\_\_和\_\_init\_\_的区别\_\_new\_\_是Python面向对象语言中一个很少用的函数,更多使用的是\_\_init\_\_这个函数。例如:class Book(object):    def __init__(self, title):

mysql设置时区

mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0

PHP单例模式

<?php/设计模式之单例模式$_instance必须声明为静态的私有变量构造函数和析构函数必须声明为私有,防止外部程序new类从而失去单例模式的意义getInstance()方法必须设置为公有的,必须调用此方法以返回实例的一个引

Java日期时间API系列30

  实际使用中,经常需要使用不同精确度的Date,比如保留到天2020042300:00:00,保留到小时,保留到分钟,保留到秒等,常见的方法是通过格式化到指定精确度(比如:yyyyMMdd),然后再解析为Date。Java8中可以用更多的方法来实现这个需求,下面使用三种方法:使用Format方法、 使用Of方法和使用With方法,性能对比,使用