python设计模式:单例模式

理论

        单例模式的特点是确保类只有一个实例化对象被创建,并让程序可以全局访问这个对象。

        常用于日志记录、数据库操作、打印机后台处理程序等,这些程序在运行过程中只能生成一个实例,以避免对同一资源产生相互冲突的请求。

        单例模式是一种经过时间考验的成熟方法,能够在不带来太多缺陷的情况下提供全局访问点。

实战

1、利用python实现经典的单例模式

class Singleton:
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)

        return cls.instance

a = Singleton()
a2 = Singleton()

print(a, a2)

# 运行结果
# <__main__.Singleton object at 0x109dbd750> <__main__.Singleton object at 0x109dbd750>

        使用类名创建对象时,python的解释器首先调用__new__方法为对象分配空间,__new__方法是由object基类提供的内置静态方法,主要的作用有两个,一是在内存中为对象分配空间,二是返回对象的引用。

        方法hasattr用于查看对象cls是否具有属性'instance'

2、懒汉实例化

        在导入模块的时候,我们可能会无意中创建一个对象,但程序根本没用到它。

        懒汉实例化的意思就是可以确保在实际需要的时候才创建对象,是一种节约资源的方式。 

class Singleton:
    _instance = None

    def __init__(self):
        if not Singleton._instance:
            print('instance未被创建')
        else:
            print('instance已经被创建:', self.getInstance())

    @classmethod
    def getInstance(cls):
        if not cls._instance:
            cls._instance = Singleton()

        return cls._instance


s = Singleton()  # 实例化对象,但instance并未被创建
Singleton.getInstance()  # 创建对象
s1 = Singleton()  # 实例化对象, instance已被创建


#  运行结果
'''
instance未被创建
instance未被创建
instance已经被创建: <__main__.Singleton object at 0x103c7f750>
'''

 3、模块级别的单例模式

        所有的模块都默认为单例,这是由python的导入行为决定的。

在导入一个模块时,python的工作方式为:

  • 检查这个模块是否已经被导入。
  • 如果已经导入,则返回这个模块的对象,如果没有导入,就导入这个模块,并实例化。

        模块在导入的时候就会被初始化,同一个模块再次被导入的时候,它不会再初始化,因为单例模式只有一个对象,它会返回同一个对象。

4、Monostate单例模式

        上面我们所说的单例模式指的是GoF(the Gang of Four, GoF)的单例设计模式,核心思想是:一个类有且只有一个对象。

        但有另一种说法,Alex Martelli认为通常程序员需要的是让实例共享相同的状态,他建议开发人员应该关注状态和行为,而不是同一性。这个概念关注的是所有对象共享相同状态,因此被称为Monostate(单态)模式。

        Monostate模式可以通过python轻松实现。

class Borg:
    __shared_state = {'1': '2'}

    def __init__(self):
        self.x = 1
        self.__dict__ = self.__shared_state


b = Borg()
b1 = Borg()
b.x = 4

print(b)
print(b1)
print(b.__dict__)
print(b1.__dict__)


# 运行结果
'''
<__main__.Borg object at 0x10d0a5e50>
<__main__.Borg object at 0x10d1756d0>
{'1': '2', 'x': 4}
{'1': '2', 'x': 4}
'''

        python使用__dict__存储一个实例化对象中所有变量的状态。

        在上面代码中,在类初始化时我们把类属性__shared_state赋值给__dict__,经过这一步骤,Borg的所有实例化对象的__dict__都将指向__shared_state,也就是说Borg所有实例化对象的__dict__变量成为了同一个变量。

        当对象b的实例属性x发生变化,这个变化会反映到对象b的__dict__属性上,由于所有实例化对象的__dict__都指向同一个类属性__shared_state,实例属性__dict__发生变化等同于类属性__shared_state发生变化,这将导致所有实例化对象的__dict__属性发生变化。因此,在实例化对象b的属性x发生变化时,另一个实例化对象b1的实例属性x也会随着发生变化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值