zoukankan      html  css  js  c++  java
  • 单例实现方式

    方式一、利用@classmethod类方法

      缺点:如果部调用方法属性,直接类的实例化,则不是单例

    # 多次实例化得到的实例是指向同一个实例(对象)
    IP = '1.1.1.1'
    PORT = 3306
    
    
    class MySQL:
        __instance = None
        
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
        
        @classmethod
        def from_conf(cls):
            if cls.__instance is None:
                cls.__instance = cls(IP, PORT)
                return cls.__instance
            return cls.__instance
    
    
    obj1 = MySQL.from_conf()
    obj2 = MySQL.from_conf()
    
    
    print(obj1)
    print(obj2)
    # <__main__.MySQL object at 0x00000000028F7B00>
    # <__main__.MySQL object at 0x00000000028F7B00>

    方法二、利用装饰器实现单例之完全单例

    def singleton(cls):
        def warp(*args, **kwargs):
            if cls._instance is None:
                obj = cls(*args, **kwargs)
                return obj
            return cls._instance
    
        return warp
    
    
    @singleton
    class MySQL:
        _instance = None
    
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    
    print(MySQL('1.1.1.1', 3306))
    print(MySQL('1.1.1.1', 3307))
    
    # <__main__.MySQL object at 0x0000000001F87390>
    # <__main__.MySQL object at 0x0000000001F87390>

    方式二、利用装饰器实现单例之不传参数单例,传参不单例

    IP = '1.1.1.1'
    PORT = 3308
    
    
    def singleton(cls):
        _instance = cls(IP, PORT)
        
        def warpper(*args, **kwargs):
            if args or kwargs:
                obj = cls(*args, **kwargs)
                return obj
            return _instance
        
        return warpper
    
    
    @singleton
    class MySQL:
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    
    obj1 = MySQL()
    obj2 = MySQL()
    obj3 = MySQL('1.1.1.2',3309)
    obj4 = MySQL('1.1.2.11',3310)
    print(obj1)
    print(obj2)
    print(obj3)
    print(obj4)
    print(obj3.port)
    print(obj4.port)
    
    # <__main__.MySQL object at 0x00000000028C7B38>
    # <__main__.MySQL object at 0x00000000028C7B38>
    # <__main__.MySQL object at 0x00000000028C7BA8>
    # <__main__.MySQL object at 0x00000000028C7C18>
    # 3309
    # 3310

     方法三、基于元类实现单例:

    IP = '1.1.1.1'
    PORT = 3309
    
    
    class Myteta(type):
        def __init__(self, class_name, class_bases, class_dic):
            # 这里的self 其实就是MySQL
            instance = self(IP, PORT)
            self.__instance = instance
        
        def __call__(self, *args, **kwargs):
            # self = MySQL这个类
            if args or kwargs:
                obj = self.__new__(self)
                self.__init__(obj, *args, **kwargs)
                return obj
            return self.__instance
    
    
    class MySQL(metaclass=Myteta):  # MySQL = Mymeta(....)
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    
    obj1 = MySQL()
    obj2 = MySQL()
    obj3 = MySQL()
    obj4 = MySQL('1.1.1.10', 3317)
    print(obj1)
    print(obj2)
    print(obj3)
    print(obj4)
    
    # <__main__.MySQL object at 0x00000000021D7BE0>
    # <__main__.MySQL object at 0x00000000021D7BE0>
    # <__main__.MySQL object at 0x00000000021D7BE0>
    # <__main__.MySQL object at 0x00000000021D7C50>
  • 相关阅读:
    单例模式
    maven版本对应的jdk
    DateUtil
    多级反向代理java获取真实IP地址
    springcloud初次zuul超时报错com.netflix.zuul.exception.ZuulException:Forwarding error
    spring cloud-config的client中/refresh的端点报错401
    spring Cloud-eureka的保护模式
    spring cloud的配置
    spring boot部署中executable的系统服务
    登陆SQL Server 2000数据库提示超时已过期的解决方法
  • 原文地址:https://www.cnblogs.com/qianzhengkai/p/10808968.html
Copyright © 2011-2022 走看看