zoukankan      html  css  js  c++  java
  • 单例模式

    单例模式:基于某种方法实例化多次得到实例是同一个。

    为什么用单例模式:当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例

    # 设计模式  23种设计模式
    # 单例模式:整个过程中只有一个实例,所有生成的实例都指向同一块内存空间
    
    # 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_sigleton(cls):
            import settings
            if not cls._instance:
                cls._instance = cls(settings.PORT,settings.HOST)
            return cls._instance
    
    # 每次调用get_sigleton拿到的对象都是同一个
    s1 = Sql.get_sigleton()
    s2 = Sql.get_sigleton()
    print(s1)
    print(s2)
    s4=Sql('33306','192.168.1.1')
    print(s4)
    
    # 第二种:通过装饰器
    # 当用户输入端口和地址,实例化产生新对象
    # 当用户不输入端口和地址,每次拿到的对象,都是同一个
    # def get_sigleton(cls):
    #     # cls就是Sql这个类
    #     import settings
    #     _instance = cls(settings.PORT,settings.HOST)
    #     def wraper(*args,**kwargs):
    #         if len(args) != 0 or len(kwargs) != 0:
    #             # 表示传了参数,生成新对象
    #             res = cls(*args,**kwargs)
    #             return res
    #         else:
    #             return _instance
    #     return wraper
    
    def get_sigleton(cls):
        _instance = None
        def wrapper(*args,**kwargs):
            if len(args) != 0 or len(kwargs) != 0:
                # 表示传了参数,生成新对象
                res = cls(*args,**kwargs)
                return res
            else:
                import settings
                nonlocal _instance
                if not _instance:
                    _instance = cls(settings.PORT,settings.HOST)
                return _instance
        return wrapper
    
    @get_sigleton    #会把下面的Sql当中参数传入,相当于:Sql=get_sigleton(Sql)
    class Sql():
        def __init__(self,port,host):
            self.port = port
            self.host = host
    
    s1 = Sql()
    s2 = Sql()
    s3=Sql('33306','192.168.1.1')
    s4=Sql('33306','192.168.1.1')
    print(s1)
    print(s2)
    print(s3)
    print(s4)
    
    # 第三种:通过元类
    # 当用户输入端口和地址,实例化产生新对象
    # 当用户不输入端口和地址,每次拿到的对象,都是同一个
    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('3306','192.0.0.1')
    print(s1)
    print(s2)
    print(s3)
    
    # 第四种:通过模块导入(python的模块是天然的单例)
    def test1():
        from sigleton import s1
        print(s1)
    
    def test2():
        from sigleton import s1 as s2
        print(s2)
    
    test1()
    test2()
    from sigleton import s1
    from sigleton import Sql
    s3 = Sql('3306','192.0.0.1')
    print(s1)
    print(s2)
    print(s3)
    
  • 相关阅读:
    java基础学习总结——哈希编码
    java基础学习总结——static关键字
    java基础学习总结——方法的重载(overload)
    java基础学习总结——流
    java基础学习总结——线程(二)
    java基础学习总结——线程(一)
    阻塞队列---ArrayBlockingQueue,LinkedBlockingQueue,DelayQueue源码分析
    hashCode 一致性hash 算法
    byte以及UTF-8的转码规则
    vue cli 解决跨域 线上 nginx 反向代理配置
  • 原文地址:https://www.cnblogs.com/yushan1/p/11461571.html
Copyright © 2011-2022 走看看