一、重写 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))