前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python3实现单例模式

python3实现单例模式

作者头像
py3study
发布2020-01-03 11:36:44
2.8K0
发布2020-01-03 11:36:44
举报
文章被收录于专栏:python3

单例模式指确保某个类在整个系统中只存在一个实例的一种设计模式 使用单例模式的好处: 1、每个实例都会占用一定的内存资源,且初始化实例时会影响运行性能,所以当整个系统只需一个实例时,使用单例模式不仅可减少资源占用,而且因为只初始化一次,还可以加快运行性能。例如当程序通过一个类来读取配置信息,而程序多个地方需要使用配置信息,这时整个程序运行过程中只需一个实例对象即可,可减少占用内存资源,同时还可以保证程序在多处地方获取的配置信息一致。 2、使用单例模式可进行同步控制,计数器同步、程序多处读取配置信息这些情景下若只存在一个实例,即可保证一致性。

在python中,一般可使用一下4种方式实现单例模式:

1、通过模块调用 2、使用__new__方法 3、使用装饰器 4、使用元类(metaclass)

一、通过模块调用

做法:将需要实现单例的类写在模块文件中,然后通过import引入该模块,即可得到单例对象。 原理:在python3中,首次导入模块文件时,会在程序目录下的__pycache__目录中生成pyc文件,之后再导入时,将直接加载pyc文件。从而实现单例。

实现代码:

  • module_demo.py class singleton_cal: def foo(self): pass export_singleton = singleton_cal()
  • use_module.py from module_demo import export_singleton a = export_singleton from module_demo import export_singleton b = export_singleton print(a == b) print(id(a) == id(b))
python3实现单例模式
python3实现单例模式

可发现,多次调用/导入模块,使用的都是同一个实例对象

二、使用__new__方法

_new__与_init__的区别: __new\:创建实例对象时调用的构造方法 _init_:初始化方法,用于设置实例的相关属性 python创建实例时,会先调用__new__构造方法,然后使用__init__进行实例初始化。 我们可以通过__new__来影响实例的创建,从而实现单例。

实现代码:

  • use_new.py
代码语言:javascript
复制
class Singleton(object):
    __instance = None
    def __new__(cls,*args,**kwargs):
        if not cls. __instance:
            cls.__instance = super().__new__(cls,*args,**kwargs)
        return cls.__instance

a = Singleton()
b = Singleton()
print(a == b)
print(id(a) == id(b))
python3实现单例模式
python3实现单例模式

上面代码中,声明了一个私有类变量__instance,当__instance不为None时,代表系统中已有实例,直接返回该实例,若__instance为None时,表示系统中还没有该类实例,则创建新实例并返回。

三、使用装饰器

  • use_decorator.py
代码语言:javascript
复制
from functools import wraps

def singleton(cls):
    instances = {}
    @wraps(cls)
    def getinstance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return getinstance

@singleton
class singleCls(object):
def foo(self):
    pass
a = singleCls()
b = singleCls()
print(a == b)
print(id(a) == id(b))
python3实现单例模式
python3实现单例模式

只有当第一次调用singleCls时,装饰器才会从instances={}开始执行,之后调用singleCls时,都只执行getinstance函数,这是装饰器的特性,利用这个特性,当我们多次调用singleCls时,在getinstance函数中判断该类是否存在于instances字典中,若不存在,则创建该类实例并加入instances字典中,并返回字典中该类的实例;若存在,则直接返回字典中该类的实例。可利用该装饰器为多个类实现单例。

四、使用元类(metaclass)

元类创建了所有的类型对象(包括object对象),系统默认的元类是type。

python3实现单例模式
python3实现单例模式

实例,类,父类,元类的关系可表示为下图

python3实现单例模式
python3实现单例模式

元类中的__call方法,在已该类为元类的类创建实例时调用,例如:类A以类B为元类,当A创建实例时,B中的\call将会被调用。利用\call__可实现对实例创建的控制。

实现代码:

  • use_metaclass.py
代码语言:javascript
复制
class SingletonMeta(type):
    __instance = None
    def __call__(cls,*args,**kwargs):
        if not cls.__instance:
            cls.__instance = type.__call__(cls,*args,**kwargs)
        return cls.__instance

class myclass(metaclass = SingletonMeta):
    def foo(self):
        pass

a = myclass()
b = myclass()
print(a==b)
print(id(a)==id(b))
python3实现单例模式
python3实现单例模式

自定义元类时,通常继承自type,声明一个私有类变量__instance保存类实例,当__instance为None时,调用type的__call__方法为类创建实例,保存到__instance并返回;若__instance不为None,则直接返回__instance,不重新创建实例。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/09/27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在python中,一般可使用一下4种方式实现单例模式:
  • 一、通过模块调用
  • 二、使用__new__方法
  • 三、使用装饰器
  • 四、使用元类(metaclass)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档