【Python】单例模式的实现

单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保一个类只有一个实例对象。

单例模式只生成一个实例对象,减少了对系统资源的开销,当一个对象的产生需要较多的资源,如读取配置文件、产生其他依赖时,可以产生一个“单例对象”然后永久驻留内存中,从而极大降低开销。

单例模式的应用场景

  1. 在资源共享的情况下,避免由于资源操作时导致的性能或损耗等。例如日志文件,应用配置。
  2. 在控制资源的情况下,方便资源之间的互相通信。例如线程池等。

单例模式的应用实例包括:a.网站的计数器;b.应用配置;c.多线程池;d.数据库配置,数据库连接池;e.应用程序的日志应用等。

单例模式的实现

  1. 基于__new__方法实现
    当实例化一个对象时,是先执行类的__new__方法(如果没有重写这个方法,那么会默认调用object.new)来实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,可以基于这个原理实现单例模式。
```python
class MySingleton:
    __obj = None # 类属性

    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            print('new...')
            cls.__obj = object.__new__(cls)
        return cls.__obj

    def __init__(self,name):
        print('init...')
        self.name = name

a = MySingleton("euansu")
b = MySingleton("nange")
print(a)
print(b)
print(a.name)
print(b.name)

通过如上方法生成的单例对象还存在问题,这里简单输出打印一下结果。

new…
init…
init…
<main.MySingleton object at 0x00000144B0F452B0>
<main.MySingleton object at 0x00000144B0F452B0>
nange
nange

不难发现,如上的代码在执行的时候进行了一次实例化和两次初始化,这不是我们所希望的,所以需要进行一个简单的判断,如果对象已经完成了初始化,就不再进行初始化过程。

class MySingleton:
    __obj = None # 类属性
    __init_flag = True # 判断实例对象是否进行过初始化

    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            print('new...')
            cls.__obj = object.__new__(cls)
        return cls.__obj

    def __init__(self,name):
        if self.__init_flag==True:
            print('init...')
            self.name = name
            self.__init_flag = False

a = MySingleton("euansu")
b = MySingleton("nange")
print(a)
print(b)
print(a.name)
print(b.name)

再次执行代码,得到如下运行结果。

new…
init…
<main.MySingleton object at 0x00000275BD1B52B0>
<main.MySingleton object at 0x00000275BD1B52B0>
euansu
euansu

进行了一次实例化和一次初始化。

  1. 使用模块
    编写一个模块MySingleton.py文件,代码如下:
class Singleton:
    def __init__(self,name):
        print("init...")
        self.name = name

singleton = Singleton("euansu")

如上,生成了一个类的对象。在其他文件中导入此文件中的对象,这个对象即是单例模式的对象。

from MySingleton import singleton
print(singleton)
print(singleton.name)

执行代码,得到如下结果:

init…
<MySingleton.Singleton object at 0x000001DF272798B0>
euansu

  1. 使用装饰器
def Singleton(cls):
    instance={}
    def getsingleton(*args,**kwargs):
        if cls not in instance:
            instance[cls]=cls(*args,**kwargs)
        return instance[cls]
    return getsingleton

@Singleton
class A(object):
    a = 1
    def __init__(self,name):
        self.name = name
    def __str__(self):
        return self.name

a = A("euansu")
b = A("nange")
print(a)
print(b)

运行代码,得到如下结果:

euansu
euansu

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值