前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python单例模式你搞懂了么?我是终于懂了~

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

作者头像
小雯子打豆豆
发布2020-06-19 10:33:45
2K0
发布2020-06-19 10:33:45
举报
在看面试题的时候,突然想到以前有人问我你知道什么是单例模式么?当时的我 一脸懵逼,更别说让我写下来了,后来也没总结整理,今天就来记录下python的单例模式是什么样的,应该经常会在面试题中问到,感兴趣的小伙伴可以看看哦~

一、概念

单例模式的作用就是确保某一个类只有一个实例存在,减少多次调用实体类造成的资源浪费。

比如:在创建一个config对象的时候,要获取里面的配置文件,但是其他类也需要使用该文件,就会导致很多地方都创建实例化对象,占用内存资源,所以我们要在程序中配置只存在一个实例对象。

tips:我的一直认为像这样的代码即使不理解,拼死也要背下来,万一面试官让你写下来呢?

一、通过文件导入实现单例

代码如下:

代码语言:javascript
复制
# 创建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方法中判断是不是存在实例,如果存在就直接返回,不存在就创建。

代码语言:javascript
复制
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装饰器

思路:装饰器外部变量定义一个字典存放类的实例,第一次创建的时候,把实例保存到字典中,每次创建对象的时候,判断是否实例化过,若没有则去实例,若没有则保存该实例到字典中。

代码语言:javascript
复制
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类方法

代码语言:javascript
复制
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)

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试小助手 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档