四种单例模式

设计模式 23种设计模式

单例模式: 整个过程中只有一个实例,所有生成的实例都指向同一块内存空间

# settings

PORT=3306
HOST='127.0.0.1'
class Person():
    def __init__(self,name,age):
        self.name=name
        self.age=age

p1=Person('lqz',19)
p2=Person('nick',18)
print(p1)
print(p2)
实现单利的第一种方法(通过类的绑定方法)
当用户输入端口和地址,实例化产生新对象
当用户不输入端口和地址,每次拿到的对象,都是同一个
class Sql():
    _instance=None
    def __init__(self,port,host):
        self.port=port
        self.host=host
        
       @classmethod
    def get_sigoleton(cls):
        import settings
        if not cls._instance:
            cls._instance = cls(settings.PORT, settings.HOST)
        return cls._instance
    
s1=Sql.get_sigoleton()
s2=Sql.get_sigoleton()
s3=Sql.get_sigoleton()

print(s1)
print(s2)
print(s3)
s4=Sql('33306','192.168.1.1')
print(s4)
第二种方法:通过装饰器
当用户输入端口和地址,实例化产生新对象
当用户不输入端口和地址,每次拿到的对象,都是同一个
def get_sigoleton(cls):
    #cls就是Sql这个类
    import settings
    _instance=cls(settings.PORT, settings.HOST)
    # _instance=Sql(settings.PORT, settings.HOST)

    def wrapper(*args,**kwargs):
        if len(args)!=0 or len(kwargs)!=0:
            #表示传了参数,生成新对象
            res=cls(*args,**kwargs)
            return res
        else:
            return _instance
    return wrapper

@get_sigoleton    #会把下面的Sql当中参数传入,相当于:Sql=get_sigoleton(Sql)
class Sql():
    def __init__(self,port,host):
        self.port=port
        self.host=host
# Sql=get_sigoleton(Sql)
s1=Sql()
s2=Sql()
s3=Sql('33306','192.168.1.1')
s4=Sql('33306','192.168.1.1')
print(s1)
print(s2)
print(s3)
第三种,通过元类
当用户输入端口和地址,实例化产生新对象
当用户不输入端口和地址,每次拿到的对象,都是同一个

class Mymeta(type):
    def __init__(self,name,bases,dic):
        #self 是Sql类
        import settings
        #把实例化好的对象,放到了类的名称空间
        self._instance=self(settings.PORT, settings.HOST)
    def __call__(self, *args, **kwargs):
        #self是谁?是Sql类
        if len(args)!=0 or len(kwargs)!=0:
            obj=object.__new__(self)
            obj.__init__(*args, **kwargs)
            return obj
        else:
            return self._instance

class Sql(metaclass=Mymeta):    #相当于 Sql=Mymeta(name,bases,dic)   这个会调用 Mymeta的__init__  在里面已经向类的名称空间放了一个对象
    def __init__(self,port,host):
        self.port=port
        self.host=host

print(Sql.__dict__)
s1=Sql()
#调用元类的__call__
s2=Sql()
s3=Sql('33306','192.168.1.1')
print(s1)
print(s2)
print(s3)
第四种方法,通过模块导入模块(模块就是天然单例)

def test():
    from sigonleton import s1
    print(s1.port)
    print(s1)
def test2():
    from sigonleton import s1 as s2
    print(s2)

test()
test2()
from sigonleton import s1
from sigonleton import Sql
s2=Sql(3306,'192.168.1.1')
print(s1)
print(s2)
# sigonleton

import settings
class Sql():
    def __init__(self,port,host):
        self.port=port
        self.host=host

s1=Sql(settings.PORT,settings.HOST)
posted on 2019-09-12 21:33  十七zz  阅读(133)  评论(0编辑  收藏  举报