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

python 单例模式

时间:2018-08-03 01:00:12      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:war   完成   tor   new   其他   .com   false   __init__   print   

研究了一下python的单利模式,简单地记录一下.

1.类和实例的创建过程

技术分享图片

从创建类到初始化一个对象,简单地可以分为四个步骤:

(1)通过元类创建一个类,调用__new__完成类的创建(阶段A)

(2)初始化一个类,调用__init__,初始化一个类(阶段B)

(3)通过类创建一个对象,调用__new__(阶段D)

(4)初始化一个对象,调用__init__(阶段E)

图中阶段A,阶段B,阶段C是由元类完成的,在文件加载的时候,自动调用__new__和__init__,阶段E不是必须的.阶段D,阶段E是创建一个实例的过程,手动调用__new__和__init__.一般情况下,创建一个类只用实例化一个类,即调用__init__,而__new__的执行被隐藏了,主要是继承了父类的__new__方法

        说完了类和实例的创建过程之后,考虑一下单例模式应该在这四个阶段中哪个阶段控制比较合适?

(1)阶段A:

创建一个类的过程,也就是说类的创建并未完成.单例是建立实例上,实例的创建又是建立在类上面的,这个阶段类还没有创建,也就不太适合

(2)阶段B:

实例化一个类,这个阶段类也创建完成了,似乎有机会控制实例的个数

 (3)阶段D:

 类的创建和实例化完成了,开始创建一个实例,但还未完成,也可以控制实例的个数

 (4)阶段E:

 这个阶段,对象已经建立了,每一次实例化一个类时,对象已经建立了,控制不了实例的个数.

简单说,阶段A (创建类的过程)类没有建立,不宜控制实例数量.阶段E(类实例化的过程)实例已经创建,控制不了实例数量.在阶段B(实例化一个类)和阶段D(创建一个实例)比较容易控制实例的数量,也就最利于实现单例模式.

2.实现单例模式

(1)阶段B(实例化一个类)

主要是通过建立元类进行控制:

# B阶段
class Singleton_C(type):
    def __init__(self, *args, **kwargs):
        self.__instance = None
        super(Singleton_C, self).__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if self.__instance is None:
            self.__instance = super(Singleton_C, self).__call__(*args, **kwargs)
            return self.__instance
        else:
            return self.__instance
    
class C:
    __metaclass__ = Singleton_C
    def __init__(self):
        print I am C

a  = C() 
b  = C()
print a is b    # True

(2)阶段D(创建实例的过程)

# D阶段
class Singleton_D(object):
    ‘‘‘实例存储在Sigleton_B类的字典中‘‘‘
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, _instance):
            cls._instance = super(Singleton_B, cls).__new__(cls, *args, **kwargs)
        return cls._instance
    
# 先继承其他类时, 会导致单例模式失效    
class D(Singleton_D):
    def __init__(self):
        print I am D

a = D()
b = D()
print a is b   # True

(3)阶段D(创建实例的过程)   --- 一个伪单例模式

每一次实现的对象不同,但共用变量

# D阶段
class Singleton_D1(object):
    _store = {}
    def __new__(cls, *args, **kwargs):
        obj = super(Singleton_B1, cls).__new__(cls, *args, **kwargs)
        print cls, obj, id(cls._store), id(obj._store), id(Singleton_B1._store)
        obj.__dict__ = cls._store
        return obj

# 先继承其他类时, 会导致单例模式失效    
class F(Singleton_D1):
    def __init__(self, name):
        self.name = name

f1 = F(‘python)
f2 = F(‘singleton)
print f1 is f2 # False

(4)装饰器

def singleton(cls):
    obj = {}
    def wrapper(*args, **kwargs):
        if cls not in obj:
            obj[cls] = cls(*args, **kwargs)
        return obj[cls]
    return wrapper

@singleton
class Foo(object):
    pass

f1 = Foo()
f2 = Foo()

print f1 is f2 # True

 

python 单例模式

标签:war   完成   tor   new   其他   .com   false   __init__   print   

原文地址:https://www.cnblogs.com/chimpan/p/9410779.html

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