python的单例模式与讨论

0.背景

每种语言都有各自的单例模式,比如JAVA经典的懒汉,饿汉模式,或是double-check线程安全的单例模式等等。这里讲述两个比较好用的单例的python写法。


1. 第一种:实现__new__方法,并将一个类的实例绑定到类变量_instance上


如果对__new__不熟悉的,可以参考文章《详解Python中的__init__和__new__》,简言之,__new__是一个类静态方法,创建这个类实例的方法,而__init__是在类实例创建之后调用。所以这种单例方法与经典的类似。代码如下:

# -*- coding: utf-8 -*-

class Singleton(object):

    #重写 __new__方法
    def __new__(cls, *args):
        if not hasattr(cls, '_instance'):  #是否存在__instance变量
            cls._instance = super(Singleton, cls).__new__(cls, *args) # 如果不存在,则新建一个类实例
        return cls._instance

    @classmethod
    def get_instance(cls, *args):
        return cls.__new__(cls, *args)
  
class MyClass(Singleton): #如果想要令MyClass变为实例,则需继承即可
    pass

if __name__ == '__main__':

    one = MyClass.get_instance()
    two = MyClass.get_instance()
    print str(one == two)

第二种:写一个装饰器函数,装饰需要单例的类,并将该类的单实例缓存下来


当调用单例类的的构造函数时,会先调用singleton函数,检查该类是否已经存在一个实例了。这种不仅是单例的一种方式,也是做缓存的一种方式,能够加快获取速度,非常经典。
# -*- coding: utf-8 -*-
from functools import wraps
def singleton(cls, *args, **kw): #装饰器函数
    instances = {}  # 所有的单例的实例都在这个instances字典中

    @wraps(cls)
    def _singleton():
        if cls not in instances:  # 当cls不在instances中
            instances[cls] = cls(*args, **kw)  # 则新建一个实例
        return instances[cls] # 然后从instances中取
    return _singleton

@singleton
class MyClass2(object): # 如果想要令MyClass2变为实例,则需在该类写上 “@singleton”即可,更加读者一看就明了此类是一个实例类

    def __init__(self):  #只有 cls不在instances中,才会调用此__init__方法
        pass

if __name__ == '__main__':

    one = MyClass2()
    two = MyClass2()
    print str(one == two)

这两种单例方式,都非常经典,第一种更容易理解,第二种更加的pythonic,按个人喜欢使用。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值