python的单例模式 Singleton

python的单例模式 Singleton

使用元类metaclass来创建单例

元类(metaclass)可以控制类的创建过程,它主要做三件事:

  • 拦截类的创建

  • 修改类的定义

  • 返回修改后的类

说明一下python中几个特殊的方法和名词的解释:

__new__()方法的作用是为类的对象分配内存空间; 一般不会去重写该方法,除非你确切知道怎么做,什么时候你会去关心它呢,它作为构造函数用于创建对象,是一个工厂函数,专用于生产实例对象。著名的设计模式之一,单例模式,就可以通过此方法来实现。在自己写框架级的代码时,可能你会用到它,我们也可以从开源代码中找到它的应用场景,例如微型 Web 框架 Bootle 就用到了

__init__()方法的作用是为类对象进行初始化

__call__()方法的作用是使类实例对象能够像函数一样来调用,因此在创建类的对象的时候就会调用__call__()

注意:如果__new__()没有返回cls(即当前类)的实例,那么当前类的__init__()方法是不会被调用 的。如果__new__()返回其他类(新式类或经典类均可)的实例,那么只会调用被返回的那个类的__init__()构造方法

另外,__init__方法中除了self之外定义的参数,都将与__new__方法中除cls参数之外的参数是必须保持一致或者等效。

super():返回其上一级父类的方法

type:是元类,即所有类的基础类。可以用__metaclass__ 来标识

如果想自己定义的类是单例形式,只要从Singleton类继承即可

创建单例的两种方式:

方式1:

class Singleton(type):
    def __new__(cls, name,bases,attrs):
        print "run __new__() ...."
        cls.__instance = None
        return  super(Singleton,cls).__new__(cls,name,bases,attrs)

    def __call__(self, *args, **kwargs):
        print "run __call__() ..."
        if self.__instance is None:
            print "返回单例对象..."
            self.__instance = super(Singleton,self).__call__(*args, **kwargs)
        return self.__instance

class MyClass(object):
    __metaclass__ = Singleton
    def __init__(self, name):
    	print "run __init()__ ..."
        self.name = name
    def get_name(self, name):
        return self.name

dp_1 = MyClass("nlj")
dp_2 = MyClass("wangwu")
print dp_1.name, id(dp_1)
print dp_2.name, id(dp_2)
print (dp_1 is dp_2)

运行结果:

run __new__() ....
run __call__() ...
返回单例对象...
run __init()__ ...
run __call__() ...
nlj 140294620061776
nlj 140294620061776
True

方式2:

class Singleton(type):
   
    def __call__(cls, *args, **kwargs):
        print 'call Singleton __call__'
        if not hasattr(cls, '_instance'):     
            cls._instance = super(Singleton,cls).__call__(*args, **kwargs)
        return cls._instance

class MyClass(object):
    __metaclass__ = Singleton
    def __init__(self, name):
        self.name = name
    def get_name(self, name):
        return self.name

dp_1 = MyClass("nlj")
dp_2 = MyClass("wangwu")
print dp_1.name, id(dp_1)
print dp_2.name, id(dp_2)
print (dp_1 is dp_2)

返回结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值