Python基础7——单例模式

半臻
• 阅读 2806

15 单例模式

15.1 init和new方法

执行步骤

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

15.1.1 __init__方法

__init__ 是构造方法

其实最先调用的方法是new方法,但是大部分情况下是不使用new方法

class Test(object):
    def __init__(self):
        print("这是init方法")

t = Test()

15.1.2 __new__方法

__new__

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

new方法的作用

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

  2. 返回对象的引用

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


class Person(object):
    def __init__(self):
        print("这是init方法")

    def __new__(cls,*args,**kwargs): #cls代表类对象本身
        print("这是new方法",cls)


p = Person()
print(pe)
# 运行结果
# 这是new方法 <class '__main__.Person'> 
# None

注意!!!:并没有执行init方法

第一种写法

# 重写new方法
class Person(object): # object提供的new方法
    def __init__(self):
        print("init")

    def __new__(cls,*args,**kwargs):#cls表示这个类
        print("new")   # 先执行new方法的代码
        res = object.__new__(cls) #调用父类的new方法
        print(res) #res就是实例化后的对象的引用
           return res #将实例后的结果进行返回

p2 = Person()

# 输出结果
# new
# <__main__.Person object at 0x000001C67F368A48>
# init

第二种写法

# 重写new方法
class Person(object): # object提供的new方法
    def __init__(self):
        print("init")

    def __new__(cls,*args,**kwargs):#cls表示这个类
        print("new")   # 先执行new方法的代码
           return super().__new__(cls)

p2 = Person()

# 输出结果
# new
# <__main__.Person object at 0x000001C67F368A48>
# 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__方法实现单例模式

# 无论实例化多少次,都实例化一个实例

class Exam(object):
    # 记录第一个被创建的对象引用
    ins = None #类属性

    def __init__(self):
        print("init方法")

    def __new__(cls,*agrs,**kwargs):

        if cls.ins is None: #如果为空,则创建一个
            cls.ins = object.__new__(cls)

        return cls.ins #返回唯一的实例对象

a = Exam()
print(a)
a2 = Exam()
print(a2)

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

通过装饰器的方法来实现

class Exam(object):
    ins = None


def outer(fn): #被修饰的类名
    # 创建一个字典来保存类的实例对象
    ins_dict = {} #{类名:实例,类名2:实例2}

    def inner():
        if fn not in ins_dict: #如果字典中没有对象
            # 创建一个对象,保存在字典中
            res = fn()  #实例化一个对象
            ins_dict[fn] = res #添加信息
        return ins_dict[fn]
    return inner

@outer
class Animal(object): #单例模式的类
    pass

t1 = Animal()
print(t1)
t2 = Animal()
print(t2)

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
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
Wesley13 Wesley13
3年前
java设计模式1
1:单例模式简介  单例模式是一种常用的软件设计模式,它确保某个类只有一个实例,而且自行实例化并向整个系统提供唯一的实例。总而言之就是在系统中只会存在一个对象,其中的数据是共享的  特点:    单例类只能有一个实例,所以一般会用static进行修释。    单例类必须自己创建自己的唯一实例。也就是在类中要new一个自己。    单例类必
Stella981 Stella981
3年前
Python中的__new__及其用法
\_\_new\_\_和\_\_init\_\_的区别\_\_new\_\_是Python面向对象语言中一个很少用的函数,更多使用的是\_\_init\_\_这个函数。例如:class Book(object):    def __init__(self, title):
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP单例模式
<?php/设计模式之单例模式$_instance必须声明为静态的私有变量构造函数和析构函数必须声明为私有,防止外部程序new类从而失去单例模式的意义getInstance()方法必须设置为公有的,必须调用此方法以返回实例的一个引
Wesley13 Wesley13
3年前
Java日期时间API系列30
  实际使用中,经常需要使用不同精确度的Date,比如保留到天2020042300:00:00,保留到小时,保留到分钟,保留到秒等,常见的方法是通过格式化到指定精确度(比如:yyyyMMdd),然后再解析为Date。Java8中可以用更多的方法来实现这个需求,下面使用三种方法:使用Format方法、 使用Of方法和使用With方法,性能对比,使用
Wesley13 Wesley13
3年前
C#单例
单例模式:步骤:1.定义静态私有对象2.构造函数私有化3.定义一个静态的,返回值为该类型的方法,一般以Getinstance/getInit为方法名称单例模式有懒汉和饿汉,最好使用饿汉1.饿汉式先实例化publicclassSingleton{privatestati
Stella981 Stella981
3年前
Python类中的__new__和__init__的区别
在写Python类时,或者看某些项目源码时,总是见到__init__和__new__方法,一直没有深入研究两者的区别,今天聊聊这个。__new____new__是类(class)方法。class新创建实例时,会调用__new__,它主要控制一个新实例的创建。需要知道的是,__new__是实例创建的第
Wesley13 Wesley13
3年前
Java8 方法引用的使用
一、方法引用分类1.构造函数2.静态方法3.实例方法(类型)4.实例方法(对象)二、方法引用构造函数ClassName::new,示例:/@authorKevin@date20170124/pub
Stella981 Stella981
3年前
Python中函数和方法的区别
1、函数要手动传self,方法不用传self2、如果是一个函数,用类名去调用,如果是一个方法,用对象去调用 举例说明:classFoo(object):def__init__(self):self.name"haiyan"deffunc(self):