vlambda博客
学习文章列表

python单例模式你搞懂了么?我是终于懂了~


在看面试题的时候,突然想到以前有人问我你知道什么是单例模式么?当时的我 一脸懵逼,更别说让我写下来了,后来也没总结整理,今天就来记录下python的单例模式是什么样的,应该经常会在面试题中问到,感兴趣的小伙伴可以看看哦~
一、概念
单例模式的作用就是确保某一个类只有一个实例存在,减少多次调用实体类造成的资源浪费。
比如:在创建一个config对象的时候,要获取里面的配置文件,但是其他类也需要使用该文件,就会导致很多地方都创建实例化对象,占用内存资源,所以我们要在程序中配置只存在一个实例对象。
tips: 我的 一直认为像这样的代码 即使不理解,拼 死也要背下来, 万一面试官让你写下来呢?
 一、通过文件导入实现单例
代码如下:
# 创建Singleton.py文件class A(object):   def foo(self): print('test')v = A()===============================================# 创建另一文件,调用该实例from singleton import A as a1from singleton import A as a2
print(a1, id(a1))print(a2, id(a2))

python单例模式你搞懂了么?我是终于懂了~

二、通过__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._instanceobj1 = singleton()obj2 = singleton()print(obj1, obj2)

三、装饰器

装饰器:把其他函数作为参数的函数,简单来说,就是修改其他函数功能的函数。(可以看下  )
思路:装饰器外部变量定义一个字典存放类的实例,第一次创建的时候,把实例保存到字典中,每次创建对象的时候,判断是否实例化过,若没有则去实例,若没有则保存该实例到字典中。
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)
结果:

python单例模式你搞懂了么?我是终于懂了~

四、classmethod类方法
import timeimport threadingclass 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._instancedef test(arg): obj1 = Singleton.instance() obj2 = Singleton.instance()    print(obj1, obj2)

python单例模式你搞懂了么?我是终于懂了~

但是这里要主要的是,存在多线程的时候,并不是同一个内存地址,所以要加锁,让多线程的时候也使用同一个内存地址。

python单例模式你搞懂了么?我是终于懂了~

1




历史推荐




来都来了,点个在看再走吧~~~