Python - 单列模式

1.什么叫单列模式?

    首先说一下,我们操作window系统时最常用的可视化单列模式的案列 应该就是 “任务管理器”;

    我们第一次打开任务管理器后(不关闭的情况下),不管我们再次打开多少次任务管理器,实际进入的还是第一次打开未关闭的任务管理器。

    当然也有其他例子:

    Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。

    单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

    单例模式提供了一个类只有一个特定类型的对象的机制。

  

  优点:

    1.在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。

    2.避免对资源的多重占用(比如写文件操作)。

  缺点:

    没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

 

2.实现单列模式的设计

    2.1 使用模块导入的方式

      Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:

    首先创建demo.py 代码如下:

class Test(object):
    def testSingleton(self):
        pass


obj = Test()

    用模块导入的方法直接导入obj这对象

from demo import obj

a = obj
b = obj

print(a)
print(b)

    输出结果:<demo1.Test object at 0x00000154F3FFBB00>

         <demo1.Test object at 0x00000154F3FFBB00>

 

    2.2 基于__new__魔术方法实现(推荐此方法,方便)

class Test(object):
    # __new__魔术方法,类似__init__方法,比__init__方法还先执行
    def __new__(cls, *args, **kwargs):
        # hasattr方法判断cls这个对象是否有instance这个属性,如果没有就执行if下的语句,有则跳过
        # 每一个实力化后的类都会有一个instance属性,这里不用纠结“instance怎么来的,为什么会有instance”这种问题
        if not hasattr(cls, 'instance'):
            cls.instance = super().__new__(cls)
        return cls.instance
# 把上面的代码理解为一个固定公式就行!实现单列模式的公式!


obj1 = Test()
obj2 = Test()
print(obj1)
print(obj2)

    输出结果:<__main__.Test object at 0x00000236D348BB38>

          <__main__.Test object at 0x00000236D348BB38>

 

    2.3 使用类

 

class Singleton(object):

    @classmethod
    def get_instance(cls, *args, **kwargs):
        # 利用反射,看看这个类有没有instance属性
        if not hasattr(Singleton, 'instance'):
            Singleton.instance = Singleton(*args, **kwargs)

        return Singleton.instance


s1 = Singleton()  # 使用这种方式创建实例的时候,并不能保证单例
s2 = Singleton()  # 只有使用这种方式创建的时候才可以实现单例
s3 = Singleton.get_instance()
s4 = Singleton.get_instance()

print(s1)
print(s2)
print(s3)
print(s4)

 

 

 

 

其实还有其他方法实现,但是我们只要熟练掌握两三种,就基本够用了,对初学者而言。

posted @ 2020-01-03 10:25  清酒伴歌谣  阅读(278)  评论(0编辑  收藏  举报