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

Python单实例模式

作者头像
Autooooooo
发布2020-11-09 10:23:38
4170
发布2020-11-09 10:23:38
举报
文章被收录于专栏:Coxhuang

Python单实例

#1 环境

代码语言:javascript
复制
Python3.8.1

#2 什么是单实例

单例模式就是确保一个类只有一个实例.当你希望整个系统中,某个类只有一个实例时,单例模式就派上了用场

#3 实现单实例方式

#3.1 非单实例

代码语言:javascript
复制
class MyClass(object):

    def foo(self):

        return None

obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)
print(id(obj1))
print(id(obj2))

#3.2 使用模块

代码语言:javascript
复制
class MyClass(object):

    def foo(self):

        return None

obj = MyClass()

使用:

代码语言:javascript
复制
from singleton.mysingleton import obj

python的模块就是天然的单例模式,因为模块在第一次导入的时候,会生成.pyc文件,当第二次导入的时候,就会直接加载.pyc文件,而不是再次执行模块代码.如果我们把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了

#3.3 使用装饰器

代码语言:javascript
复制
def singleton(cls):
    """装饰器函数"""

    class_instance = {} # 定义一个接受实例的类 

    def singleton_inner(*args, **kwargs):

        if cls not in class_instance: # 判断该类是否被实例化过 
            class_instance[cls] = cls(*args, **kwargs) # 没有被实例化过 -> 实例化 -> 将实例化的对象添加到字典中  

        return class_instance[cls] # 返回实例化对象 

    return singleton_inner 

@singleton
class MyClass(object):

    def foo(self):

        return None

obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)
print(id(obj1))
print(id(obj2))
20200221145958-image.png
20200221145958-image.png

在类前加个装饰器,在这里装饰器的目的只有一个,就是在类实例化前,先判断这个类有没有实例化过,如果没有,则实例化,如果实例化过,测返回之前的实例化对象

#3.4 使用类

代码语言:javascript
复制
class MyClass(object):

    def foo(self):

        return None

    @classmethod
    def get_instance(cls, *args, **kwargs):
        """实例化函数"""

        if not hasattr(cls, '_instance'):
            cls._instance = cls(*args, **kwargs)

        return cls._instance


obj1 = MyClass.get_instance()
obj2 = MyClass.get_instance()
print(obj1 is obj2)
print(id(obj1))
print(id(obj2))
obj3 = MyClass()
print(id(obj3))
20200222145424-image.png
20200222145424-image.png

以这种方式实现单实例,有两个弊端:

  1. 只有MyClass.get_instance()这样子实例化对象才能实现单实例,如果是使用MyClass()这种方式实例化,则不能实现单实例
  2. 多线程的时候,很可能会出现多个实例,因为当调用这个类方法的时候get_instance(),如果在实例化过程中__init__函数消耗很长时间,那么其他的线程的实例化,就会认为自己是第一个实例化,这样以来,就会导致出现多个实例

#3.5 重写__new__方法(推荐)

代码语言:javascript
复制
class MyClass(object):

    def foo(self):

        return None

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = super().__new__(cls)

        return cls._instance


obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)
print(id(obj1))
print(id(obj2))
20200222155934-image.png
20200222155934-image.png

一个对象的实例化过程是先执行类的__new__方法,如果我们没有写,默认会调用object的__new__方法,返回一个实例化对象,然后再调用__init__方法,对这个对象进行初始化,我们可以根据这个实现单例

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Python单实例
  • #1 环境
  • #2 什么是单实例
  • #3 实现单实例方式
    • #3.1 非单实例
      • #3.2 使用模块
        • #3.3 使用装饰器
          • #3.4 使用类
            • #3.5 重写__new__方法(推荐)
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档