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>
  • 相关阅读:
    ASP.NET使用UEditor入门与常见问题
    关于发布者策略程序集学习记录
    Myeclipse 10安装,以及Flex4插件(原)
    IE、Chrome等浏览器实现PDF预览(原)
    Oracle数据库中文显示乱码的最简单解决办法
    关于程序集的结构(2)C#和.NET2.0实战学习笔记
    关于AppDomain
    关于强名称程序集 C#和.NET2.0实战学习记录
    数据库查询·聚合分支格式化日期·思维导图&要点&误点(含示例)
    如何在SERVER2003上安装MySQL?(附安装教程及资源地址)
  • 原文地址:https://www.cnblogs.com/qianzhengkai/p/10808968.html
Copyright © 2011-2022 走看看