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

python实现单例模式的5种方法

作者头像
Tim在路上
发布2020-08-04 22:35:17
6.2K0
发布2020-08-04 22:35:17
举报
文章被收录于专栏:后台技术底层理解

单例模式

相信大家都知道单例模式

单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点。”

单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。

那么,为什么不直接使用全局变量,而要搞一个单例出来?单例到底比全局变量好在哪儿?

代码语言:javascript
复制
  首先,全局变量不能保证全局只有一个类的实例,你完全可以声明同一个类的多个实例。当然,如果你注意一点,那么用全局方法保证全局只有一个该类的实例还是可以做到的,但你得很注意,让自己不要在其他地方声明多一个实例。而单例却可以轻松的做到这一点,并能保证全局只有一个该类的实例可被访问。

  其次,相对来说,使用单例时,代码会显得优雅一些。

什么时候用单例

代码语言:javascript
复制
  单例的使用主要是在需要保证全局只有一个实例可以被访问的情况,比如系统日志的输出、操作系统的任务管理器等。

一、使用new方法

代码语言:javascript
复制
class Singleton(object):
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            orig = super(Singleton, cls)
            cls._instance = orig.__new__(cls, *args, **kw)
        return cls._instance
 
class MyClass(Singleton):
    a = 1

二、共享属性

代码语言:javascript
复制
class Borg(object):
    _state = {}
    def __new__(cls, *args, **kw):
        ob = super(Borg, cls).__new__(cls, *args, **kw)
         ob.__dict__ = cls._state
    return ob
 
class MyClass2(Borg):
    a = 1

创建实例时把所有实例的dict指向同一个字典,这样它们具有相同的属性和方法.

三、装饰器版本

代码语言:javascript
复制
def singleton(cls, *args, **kw):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance
 
@singleton
class MyClass:

四、import方法

作为python的模块是天然的单例模式

代码语言:javascript
复制
# mysingleton.py
class My_Singleton(object):
    def foo(self):
        pass
 
my_singleton = My_Singleton()
 
# to use
from mysingleton import my_singleton
 
my_singleton.foo()

五、使用元类方法

代码语言:javascript
复制
class Singleton2(type):
    def __init__(self, *args, **kwargs):
        self.__instance = None
        super(Singleton2,self).__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if self.__instance is None:
            self.__instance = super(Singleton2,self).__call__(*args, **kwargs)
        return self.__instance


class Foo(object):
    __metaclass__ = Singleton2 #在代码执行到这里的时候,元类中的__new__方法和__init__方法其实已经被执行了,而不是在Foo实例化的时候执行。且仅会执行一次。


foo1 = Foo()
foo2 = Foo()
print (Foo.__dict__)  #_Singleton__instance': <__main__.Foo object at 0x100c52f10> 存在一个私有属性来保存属性,而不会污染Foo类(其实还是会污染,只是无法直接通过__instance属性访问)

print (foo1 is foo2)  # True
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单例模式
  • 一、使用new方法
  • 二、共享属性
  • 三、装饰器版本
  • 四、import方法
  • 五、使用元类方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档