码迷,mamicode.com
首页 > 编程语言 > 详细

python单例模式控制成只初始化一次,常规型的python单例模式在新式类和经典类中的区别。

时间:2018-08-13 13:49:12      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:ret   不同   连接   bsp   span   png   round   UNC   att   

单例模式的写法非常多,但常规型的单例模式就是这样写的,各种代码可能略有差异,但核心就是要搞清楚类属性 实例属性,就很容易写出来,原理完全一模一样。

如下:

技术分享图片

源码:

class A(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, __inst):
            print(执行new)
            obj = super(A, cls).__new__(cls)
            setattr(cls, __inst, obj)
            return obj
        else:
            return cls.__dict__[__inst]

    def __init__(self, x):
        print(执行init)
        self.x = x


if __name__ == __main__:
    a1 = A(1)
    print(a1.x , a1.x)
    a2 = A(2)
    print(a2.x , a2.x)
    print(a1.x , a1.x)
    a3 = A.__new__(A)
    # a3.__init__(3)                    # a3 = A(3) 实际是调用了new和init方法,此处屏蔽调用init
    print(a3.x , a3.x)
    print(id(a1), id(a2), id(a3))

实例化了三个对象,执行结果可以猜猜:

技术分享图片

可以发现,执行了一次new,但执行了两次init,这是在新式类下运行的,python3默认是新式类,不管有没有继承object。

 

如果是python2,且不继承object,实际上是只会打印执行一次init。所以这是py2和py3的又一个区别,经典类和新式类区别非常多,新式类的反射方法也与经典类有些不同。但一般文章只说新式类和经典类的区别只是广度优先和深度优先,误导。

 

 

3、终极目标就是使python3的实例也不多执行力一次init,(因为虽然单例模式能控制成是所有类的实例指向同一个对象,但有时候的单例模式初始化是建立一个io连接或者资源池,这样每次执行初始化浪费一些时间)

两种方法,一种是增加一个类属性做标志,在init方法中增加if判断

第二种是,不使用 a = A(xxxx),而使用a = A.__new__(A),因为a = A(xxxx),实际上是a = A.__new__(A),和a.__init__(xxx) 

 

4、还有一种方式是使用装饰器,如果按照这个写法也不会执行多次init

#coding=utf8
from functools import wraps


def singleton(cls):
    print cls
    instances = {}
    @wraps(cls)
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance


@singleton
class MyClass(object):
    a = 1

m1=MyClass()
m2=MyClass()

print m1 is m2

 

python单例模式控制成只初始化一次,常规型的python单例模式在新式类和经典类中的区别。

标签:ret   不同   连接   bsp   span   png   round   UNC   att   

原文地址:https://www.cnblogs.com/ydf0509/p/9463832.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!