基于元类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Singleton(type):
def __init__(cls, *args, **kwargs): """""" cls.__instance = None super().__init__(*args, **kwargs)
def __call__(cls, *args, **kwargs): """""" if cls.__instance is None: cls.__instance = super().__call__(*args, **kwargs) return cls.__instance else: return cls.__instance
class Spam(metaclass=Singleton):
...
s1 = Spam() s2 = Spam() print(id(s1)) print(id(s2))
|
基于 new 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Singleton(object):
__instance = None
def __init__(self): ...
def __new__(cls, *args, **kwargs): if not cls.__instance: cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs) return cls.__instance
class Spam(Singleton):
...
s1 = Spam() s2 = Spam() print(id(s1)) print(id(s2))
|
基于装饰器
用闭包实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| def singleton(cls): """使用闭包的方式实现一个单例装饰器"""
__instance = {}
def _create(*args, **kwargs): if cls not in __instance: __instance[cls] = cls(*args, **kwargs) return __instance[cls] return _create
@singleton class Spam(object): ...
s1 = Spam() s2 = Spam() print(id(s1)) print(id(s2))
|
用类实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Singleton(object):
def __init__(self, cls): self.__cls = cls self.__instance = {}
def __call__(self, *args, **kwargs): if self.__cls not in self.__instance: self.__instance[self.__cls] = self.__cls(*args, **kwargs) return self.__instance[self.__cls]
@Singleton class Spam(object): ...
s1 = Spam() s2 = Spam() print(id(s1)) print(id(s2))
|
注意
Python的模块是天然的单例模式
在一个py文件中, 多次导入同一个模块, 这个模块也只有在第一次的时候被导入, 后续的该模块导入语句都不会再执行了
参考链接
https://developer.aliyun.com/article/653759