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>
  • 相关阅读:
    网站漏洞扫描工具Uniscan
    iOS 11开发教程(八)定制iOS11应用程序图标
    iOS 11开发教程(七)编写第一个iOS11代码Hello,World
    UDP转TCP隧道工具udptunnel
    iOS 11开发教程(六)iOS11Main.storyboard文件编辑界面
    Web服务评估工具Nikto
    iOS 11开发教程(五)iOS11模拟器介绍二
    网络数据修改工具netsed
    iOS 11开发教程(四)iOS11模拟器介绍一
    兼容IE getElementsByClassName取标签
  • 原文地址:https://www.cnblogs.com/qianzhengkai/p/10808968.html
Copyright © 2011-2022 走看看