~~面向对象进阶(五):单例模式~~

进击のpython

*****

单例模式


打印过东西吗?

我们一般都是怎么打印东西?

拿着一个打印机,然后把要打印的东西按顺序传到打印机

然后再打印是吧

这就是单例模式

卧槽?

那单例模式到底是什么?


其实,单例模式是一种常用的软件设计模式

在它的核心结构中只包含一个被称为单例类的特殊类

通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,

从而方便对实例个数的控制并节约系统资源

如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案

我就问你,我这么说你能看懂吗?

不光是你啊,我也整不明白啊

实践是检验真理的唯一标准

所以,还是要用代码,才能让你更直观的感受


我们可以模拟一个打印机不?

当然!毕竟面向对象是上帝模式的编程方式

上帝可是什么都能创造的!

class Printor(object):
    def __init__(self, name):
        self.name = name

    pass

    def p(self):
        print(f"我是打印{self.name}的打印机")
        pass


w = "Word"
p = "PDF"
e = "Excel"
# 做一个打印机,否则你拿啥打印啊
p1 = Printor(w)
p1.p()

p2 = Printor(p)
p2.p()

p3 = Printor(e)
p3.p()

对吧,这么写

但是你就会发现一个十分重要的问题

print(p1, p2, p3)

我他娘的整出来三个打印机!

我一个打印机就能干的活,你给我整理了三个

难搞哦

上帝的心态发生了一些变化

我可不可以只有一个打印机,然后让他自己工作呢?

你都考虑到了,上帝能没有考虑到?


  • --new-- 方法

    还记得我们以前曾经说过

    在你执行和调用类的时候,类里面的--init--方法先执行

    对吧!

    但是其实

    在执行--init--之前,先要执行--new--这个方法

    给你整个例子,要不然啊

    你都不信

    class Printor(object):
        def __init__(self, name):
            self.name = name
            print("我是init方法")
    
        def __new__(cls, *args, **kwargs):
            print("我是new方法")
    
        def p(self):
            print(f"我是打印{self.name}的打印机")
            pass
    
    
    p = Printor("w")
    
    我是new方法
    

    是不是没有调用--init--方法?

    那系统是怎么写的呢?

    她是这么写的

     def __new__(cls, *args, **kwargs):
            print("我是new方法")
            return object.__new__(cls)
    
    我是new方法
    我是init方法
    

    这个就是记住!

    然后这不就是调用了吗

    那我们的需求是不是就变成了

    我只有第一次的时候,做一个打印机,后面每一次想要打印的时候

    就用这个打印机,而不用再继续整一个了

    class Printor(object):
        l = ""
    
        def __init__(self, name):
            self.name = name
    
        def __new__(cls, *args, **kwargs):
            if cls.l == "":
                obj = object.__new__(cls)
                cls.l = obj
                return obj
            else:
                return cls.l
    
        def p(self):
            print(f"我是打印{self.name}的打印机")
            pass
    
    
    w = "Word"
    p = "PDF"
    e = "Excel"
    # 做一个打印机,否则你拿啥打印啊
    p1 = Printor(w)
    p2 = Printor(p)
    p3 = Printor(e)
    
    print(p1, p2, p3)
    

    简单的介绍一下主要的代码块

        def __new__(cls, *args, **kwargs):
            if cls.l == "":  # 在外面声明一个用来存储实例化对象的内存地址
                obj = object.__new__(cls)  # 将这个类进行实例化操作,并把地址传给了obj
                cls.l = obj  # 将实例化的地址传给l
                return obj  # 返回这个地址给self
            else:
                return cls.l  # 如果我发现你已经实例化过一个对象了,那我就用你实例化的
    

    你也发现了,我整出来的这三个打印机,实际上内存地址相同

    所以说本质上还是一个打印机的使用

    这样就完成了一个打印机干很多事的操作

    那其实,这种操作只是在重复的使用--init--方法

    那么,里面的name就被重复的覆盖然后赋值

    所以在最后你打印的name

    一定是最后放进打印机里面的属性值

    print(p1.name, p2.name, p3.name)
    

    你拿到的结果就应该是

    Excel Excel Excel
    

    对吧,没问题吧!

    这个还是挺重要的,尤其是在面试的时候

    所以说还是要看看学习一下的


*这个很有东西*
*字少也要重视*
原文地址:https://www.cnblogs.com/jevious/p/11283836.html