Python——单例模式
实现方式:
1.装饰器 实现单例模式
# 使用装饰器实现的单例模式;
“”“
创建外部函数 shoppingcar
创建一个instances字典用来保存单例
创建内部函数get_instance获取单利
判断instances字典中是否已存在单利,
若无则为第一次创建单利并保存在字典中,然后返回该单利
返回内部函数名 get_instance
”“”
def shoppingcar(cls, *args, **kwargs):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@shoppingcar
class Goods():
def __init__(self, name, price):
self.name = name
self.age = price
s1 = Goods('xx', 22)
s2 = Goods('zz', 33)
print(s1) #<__main__.Goods object at 0x000001619C875B00>
print(s2) #<__main__.Goods object at 0x000001619C875B00>
使用装饰器的单例与其他方式的单例,在使用中的区别:
使用装饰器的单例属性不会被覆盖,因为装饰器单例模式是直接返回之前生成的对象/实例,
并且不会执行init方法 重新初始化对象。
如若使用new方法构建的单例模式会重新调用init方法为了对象/实例重新进行初始化。
2.使用类 实现单例模式
class ShoppingCar():
def init():
pass
@classmethod
def get_shopping_car(cls, *args, **kwargs):
# 判断这个类有没有_instance属性
if not hasattr(ShoppingCar, "_instance"):
ShoppingCar._instance = ShoppingCar()
return ShoppingCar._instance
z = ShoppingCar.get_shopping_car()
x = ShoppingCar.get_shopping_car()
print(id(z)) # 140729453268192
print(id(x)) # 140729453268192
“”“ 以上为单线程情况实现单例 ”“”
————————————————————————————————————————————————————————————————
“”“ 以下为多线程情况实现单例 (加锁) ”“”
import threading
import time
class ShoppingCar():
# 单下划线的作用是这个变量只能在当前模块里访问,仅仅是一种提示作用
_instance_lock = threading.Lock()
def __init__(self):
pass
time.sleep(1)```
@classmethod
def get_shopping_car(cls, *args, **kwargs):
# 判断这个类有没有_instance属性
if not hasattr(ShoppingCar,'_instance'):
with ShoppingCar._instance_lock:
if not hasattr(ShoppingCar, "_instance"):
ShoppingCar._instance = ShoppingCar()
return ShoppingCar._instance
def task():
obj = ShoppingCar.get_shopping_car()
print(obj)
for i in range(10):
t = threading.Thread(target=task)
t.start()
"""
<__main__.ShoppingCar object at 0x000002E7E3B35B00>
<__main__.ShoppingCar object at 0x000002E7E3B35B00>
<__main__.ShoppingCar object at 0x000002E7E3B35B00>
<__main__.ShoppingCar object at 0x000002E7E3B35B00>
<__main__.ShoppingCar object at 0x000002E7E3B35B00>
<__main__.ShoppingCar object at 0x000002E7E3B35B00>
<__main__.ShoppingCar object at 0x000002E7E3B35B00>
<__main__.ShoppingCar object at 0x000002E7E3B35B00>
<__main__.ShoppingCar object at 0x000002E7E3B35B00>
<__main__.ShoppingCar object at 0x000002E7E3B35B00>
"""