一、概念
单例模式的作用就是确保某一个类只有一个实例存在,减少多次调用实体类造成的资源浪费。
比如:在创建一个config对象的时候,要获取里面的配置文件,但是其他类也需要使用该文件,就会导致很多地方都创建实例化对象,占用内存资源,所以我们要在程序中配置只存在一个实例对象。
tips:我的一直认为像这样的代码即使不理解,拼死也要背下来,万一面试官让你写下来呢?
一、通过文件导入实现单例
代码如下:
# 创建Singleton.py文件
class A(object):
def foo(self):
print('test')
v = A()
===============================================
# 创建另一文件,调用该实例
from singleton import A as a1
from singleton import A as a2
print(a1, id(a1))
print(a2, id(a2))
结果:多次导入该实例,其实调用的是同一个地址
二、通过__new__方法
主要思路:在一个类的new方法中判断是不是存在实例,如果存在就直接返回,不存在就创建。
class singleton(object):
def __init__(self):
pass
def __new__(cls, *args, **kwargs):
# 是否有实例,没用则创建一个实例
if not hasattr(cls, '_instance'):
singleton._instance = object.__new__(cls)
return singleton._instance
obj1 = singleton()
obj2 = singleton()
print(obj1, obj2)
三、装饰器
装饰器:把其他函数作为参数的函数,简单来说,就是修改其他函数功能的函数。(可以看下 什么是Python装饰器)
思路:装饰器外部变量定义一个字典存放类的实例,第一次创建的时候,把实例保存到字典中,每次创建对象的时候,判断是否实例化过,若没有则去实例,若没有则保存该实例到字典中。
def Singleton(cls, *args, **kargs):
_instance = {} # 创建空字典
def get_instance(*args, **kargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kargs)
return _instance[cls] # 返回实例
return get_instance # 返回内层函数
@Singleton
class Settings():
def __init__(self):
self.a = 'abc'
s1 = Settings()
s2 = Settings()
print(s1, s2)
结果:
四、classmethod类方法
import time
import threading
class Singleton(object):
_instance_lock = threading.Lock() # 加锁
def __init__(self):
time.sleep(1)
@classmethod
def instance(cls, *args, **kwargs):
with Singleton._instance_lock: # 加锁
if not hasattr(Singleton, '_instance'):
Singleton._instance = Singleton(*args, **kwargs)
return Singleton._instance
def test(arg):
obj1 = Singleton.instance()
obj2 = Singleton.instance()
print(obj1, obj2)
但是这里要主要的是,存在多线程的时候,并不是同一个内存地址,所以要加锁,让多线程的时候也使用同一个内存地址。