单例模式

若如初见. 提交于 2020-01-29 04:30:41

(一)、单例模式
设计模式:基于类做的一些设计,以此来实现数据封装的管理
单例模式:最常见的一种设计模式,经常被考到(单例模式:一个类只能生成一个实例)

#单例模式的本质:做实例化的时候,判断有没有类变量_instance,
如果没有,生成一个Singleton的父类对象object的实例,赋值给_instance(只会做一次),返回cls._instance
如果有这个_instance类变量,直接返回cls._instance
(或者本质这样理解:通过__new__的if判断逻辑,判断是否生成过实例地址,如果没生成,生成一个,生成了呢?就用老的那个地址。)

class Singleton(object):
    def __init__(self):
        self.c=1000

    def __new__(cls, *args, **kw):         #规定,__new__必须返回一个实例(当前类的实例或者父类的实例)
        #如果cls这个类没有类变量_instance,则会执行if下的代码
        if not hasattr(cls, '_instance'):
            orig = super(Singleton, cls)   #找到父类的类对象object,也可以写成orig = super()
            cls._instance = orig.__new__(cls, *args, **kw)    #可以写成不带参数,cls._instance = orig.__new__(cls)
        return cls._instance               #__new__返回的是父类object的实例

class MyClass(Singleton):     #MyClass类继承于类Singleton,会把__new__也给继承下来
    a = 1                     #类变量
    def __init__(self):
        self.b = 100          #实例变量
            
#生成两个实例one和two,用什么类做实例化,这个类名就会传给cls
one = MyClass()               #MyClass类传给cls
two = MyClass()

two.a = 3       

#one和two完全相同,可以用id(), ==, is进行检测
print (id(one))      #执行结果:2941613793520
print (id(two))      #执行结果:2941613793520
print (one == two)   #执行结果:True
print (one is two)   #执行结果:True

print(one.a)         #执行结果:3
print(two.a)         #执行结果:3
one.b=101
print(one.b)         #执行结果:101
print(two.b)         #执行结果:101

"""Singleton和MyClass同时都有__init__方法
class Singleton(object):
    def __init__(self):
        print("Singleton的__init__方法的调用")
        self.c=1000

    def __new__(cls, *args, **kw): 
        print("__new__方法的调用")       
        if not hasattr(cls, '_instance'):
            orig = super(Singleton, cls)   
            cls._instance = orig.__new__(cls, *args, **kw)    
        return cls._instance        #__new__返回的是父类object的实例      

class MyClass(Singleton):     #MyClass类继承于类Singleton,会把__new__也给继承下来
    a = 1                     
    def __init__(self):
        print("MyClass的__init__方法的调用")       
        self.b = 100          
            
MyClass()
 
#执行结果:
__new__方法的调用
MyClass的__init__方法的调用

#上面的执行结果说明:说明Singleton的__init__方法不会被调用,并且是先调用Singleton的__new__方法,再调用MyClass的__init__方法(表示是先有地址,才能设定初始化值)

"""

上述例子中用到的一个知识点:hasattr
>>> class P:
...     Count = 0
...     def __init__(self,name):
...         self.name = name
...
>>> p = P("YQQ")
>>> hasattr(p,"name")       #判断实例里面有没有这个属性
True
>>> hasattr(p,"Count")
True
>>> getattr(p,"Count")      #获取实例里面的属性值
0
>>> getattr(p,"name")
'YQQ'

"""

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!