方式一、利用@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>