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

    单列模式

    一、单列模式

    1.1 什么是单列模式

    1. 整个过程中只是一个实例,所有生成的实例都指向同一块内存地址
    2. 基于某种方法实例化多次得到的实例是同一个

    理解:

    就像a= 1``b=1``c =1对a、b、c的地址进行打印,都是相同的

    1.2 为啥用单列模式

    当实例化多次得到的对象中存放的属性都一样的情况,应该多个对象指向同一个内存,即同一个实例。

    二、实现单列模式

    模块settings

    #settings.py
    PORT=3306
    HOST='127.0.0.1'
    

    方法1(通过类的绑定方法)

    要求:

    1. 当用户输入端口和地址,实例化产生新对象
    2. 当用户不输入端口和地址,每次拿到的对象,都是同一个
    class Sql():
        _instance = None
    
        def __init__(self, port, host):
            self.port = port
            self.host = host
    
        @classmethod
        def get_sigoleton(cls):
            import settings
            if cls._instance:
                return cls._instance
            else:
                cls._instance = cls(settings.PORT, settings.HOST)
                return cls._instance
    
    
    s1 = Sql.get_sigoleton()
    s2 = Sql.get_sigoleton()
    s3 = Sql.get_sigoleton()
    print(s1)  # <__main__.Sql object at 0x000001D7F1BE1188>
    
    print(s2)  # <__main__.Sql object at 0x000001D7F1BE1188>
    
    print(s3)  # <__main__.Sql object at 0x000001D7F1BE1188>
    s4 = Sql('33306', '192.168.1.1')
    print(s4)  # <__main__.Sql object at 0x000001B2AD820348>
    

    法二、通过装饰器

    要求:

    1. 当用户输入端口和地址,实例化产生新对象
    2. 当用户不输入端口和地址,每次拿到的对象,都是同一个
    def get_sigoleton(cls):
        # cls就是装饰的时候把Sql传入
        _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_sigoleton
    # 会把下面的Sql当作参数传入,相当于:Sql = get_sigoleton(Sql)
    class Sql():
        def __init__(self, port, host):
            self.port = port
            self.host = host
    
    
    s1 = Sql()
    s2 = Sql()
    s3 = Sql()
    print(s1)  # <__main__.Sql object at 0x000001E7AED841C8>
    
    print(s2)  # <__main__.Sql object at 0x000001E7AED841C8>
    
    print(s3)  # <__main__.Sql object at 0x000001E7AED841C8>
    
    

    法三、通过元类

    要求:

    1. 当用户输入端口和地址,实例化产生新对象
    2. 当用户不输入端口和地址,每次拿到的对象,都是同一个
    class Mymeta(type):
        def __init__(self, name, bases, dic):
            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()
    

    法四、通过通过模块导入(python的模块是天然的单例)

    要求:

    1. 当用户输入端口和地址,实例化产生新对象
    2. 当用户不输入端口和地址,每次拿到的对象,都是同一个
    #sigonleton.py
    import settings
    class Sql():
        def __init__(self,port,host):
            self.port = port
            self.host = host
    s1 = Sql(settings.PORT,settings.HOST)
            
    
    def test():
        from sigonleton import s1
        print(s1.port)
        print(s1)
    def teat2():
        from sigonleton import s1 as s2
        print(s2)
    test()
    teat2()
    
  • 相关阅读:
    jquery练习(赋予属性值)
    jquery练习
    jquery表单对象属性选择器
    jquery表单选择器
    jquery子元素选择器
    jquery属性选择器(同时匹配多个条件)
    jquery属性选择器
    jquery属性选择器(匹配具有指定属性的元素)
    jquery可见性选择器(综合)
    方法的递归
  • 原文地址:https://www.cnblogs.com/SkyOceanchen/p/11461630.html
Copyright © 2011-2022 走看看