python 单例模式实现

it2026-06-14  5

一、重写 new 方法

# -*- coding: utf-8 -*- # Python 单例模式实现 import pysnooper import threading # 方式一, 重写__new__ 方法 class SingletonOne(object): _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(SingletonOne, cls).__new__(cls, *args, **kwargs) return cls._instance def __init__(self): pass class SingletonTwo(object): _instance = {} # @pysnooper.snoop() def __new__(cls, *args, **kwargs): key = str(args) + str(kwargs) print('key:', key) if key not in cls._instance: cls._instance[key] = super().__new__(cls) return cls._instance[key] def __init__(self, name): self.name = name # 多线程 class SingletonLock(object): _instance = {} _instance_lock = threading.Lock() def __new__(cls, *args, **kwargs): key = str(args) + str(kwargs) if key in cls._instance: return cls._instance[key] cls._instance_lock.acquire() # 获取锁对象 try: if key in cls._instance: return cls._instance[key] cls._instance[key] = super().__new__(cls) return cls._instance[key] finally: cls._instance_lock.release() # 释放锁对象 def __init__(self, name): self.name = name def task(name): obj = SingletonLock(name) print(obj, 'id: ', id(obj)) if __name__ == "__main__": s1 = SingletonOne() s2 = SingletonOne() print('SingletonOne:', id(s1) == id(s2)) s3 = SingletonTwo('ma') s4 = SingletonTwo('ma') print('SingletonTwo:', id(s3) == id(s4)) # 多线程调用 for i in range(10): t = threading.Thread(target=task, args=['ma', ]) t.start() # 正常调用 c1 = SingletonLock('ma') c2 = SingletonLock('ma') print('SingletonLock:', id(c1) == id(c2))

二、装饰器方式

# 方式二, 装饰器 def singleton(cls): _instance = {} def _singleton(*args, **kwargs): key = str(args) + str(kwargs) print('key:', key) if key not in _instance: _instance[key] = cls(*args, **kwargs) return _instance[key] return _singleton @singleton class A(object): def __init__(self, x): self.x = x if __name__ == "__main__": a1 = A(2) a2 = A(3) print('A:', id(a1) == id(a2))

三、元类的方式

class SingletonType(type): _instance = {} def __init__(self, *args, **kwargs): super(SingletonType, self).__init__(*args, **kwargs) def __call__(cls, *args, **kwargs): # 这里的cls,即Foo类 print('cls', cls) key = str(args) + str(kwargs) if key not in cls._instance: cls._instance[key] = cls.__new__(cls, *args, **kwargs) return cls._instance[key] # 线程锁的方式 class SingletonType(type): _instance_lock = threading.Lock() def __call__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): with SingletonType._instance_lock: if not hasattr(cls, "_instance"): cls._instance = super(SingletonType, cls).__call__(*args, **kwargs) return cls._instance class Foo(metaclass=SingletonType): # 指定创建Foo的type为SingletonType def __init__(self, name): self.name = name def __new__(cls, *args, **kwargs): return object.__new__(cls) obj1 = Foo('xx') obj2 = Foo('xx') print(id(obj1) == id(obj2))
最新回复(0)