python四种实现单例模式

# _*_ coding:utf-8 _*_
'''
    @author:xianyt
    @date:2018/
    @func:
'''
'''
    在默认的情况下创建多个对象的ID不相同,如果想要设置为单例模式,可以通过__new__()方法中的__instance
在__new__方法中把类实例绑定到类变量_instance上,如果cls._instance为None表示该类还没有实例化过,实例化该类并返回。如果cls_instance不为None表示该类已实例化,直接返回cls_instance
'''
'''第一种实现单例模式'''

print('---------第一种-------------')
class Single(object):
    __instance=None
    def __new__(cls):
        if cls.__instance==None:
            # 如果__instance为空说明这次是第一次创建实例
            # 通过父类的__new__创建实例
            cls.__instance=object.__new__(cls)
            return cls.__instance
        else:
            #返回上一个对象的引用
            return cls.__instance
a = Single()
b = Single()
print(id(a)==id(b))


'''
方式二
共享属性;所属单例就是所有引用(实例、对象)拥有相同的状态和行为
同一个类的所有实例天然拥有相同的行为
只需要保证同一个类的所有实例具有相同的状态
所有实例共享属性的最简单最直接的方法就是__dict__属性属性指向同一个字典(dict)
'''
print('---------第二种-------------')
class Borg(object):
    _state = {}
    def __new__(cls, *args, **kw):
        ob = super(Borg, cls).__new__(cls, *args, **kw)
        ob.__dict__=cls._state
class MyClass2(Borg):
    a = 1
one = MyClass2()
two = MyClass2()
print(id(one)==id(two))



'''
    本质上上算上方式1
    使用_metaclass__的高级python用法
'''
print('---------第三种(python2)-------------')
class Singleton2(type):
    def __init__(cls, name, bases, dict):
        super(Singleton2, cls).__init__(name, bases, dict)
        cls._instance = None

    def __call__(cls, *args, **kw):
        if cls._instance is None:
            cls._instance = super(Singleton2, cls).__call__(*args, **kw)
        return cls._instance


class MyClass3(object):
    __metaclass__ = Singleton2
one = MyClass3()
two = MyClass3()

print(id(one) == id(two))



print('---------第三种(python3)-------------')


class Singleton3(type):
    def __new__(cls, name, bases, attrs):
        attrs["instance"] = None
        return super(Singleton3, cls).__new__(cls, name, bases, attrs)

    def __call__(cls, *args, **kw):
        if cls.instance is None:
            cls.instance = super(Singleton3, cls).__call__(*args, **kw)
        return cls.instance


class MyClass4(metaclass=Singleton3):
    pass

one = MyClass4()
two = MyClass4()

print(id(one) == id(two))

'''
    使用高级装饰器
    这是一种更pythonic,更elegant的方法
'''
print('---------第四种-------------')
def singleton(cls):
    instance = {}
    def _singleton(*args, **kwargs):
        if cls not in instance:
            instance[cls] = cls(*args, **kwargs)
        return instance[cls]
    return _singleton

@singleton
class MyClass4(object):
    a = 1
    def __init__(self, x=0):
        self.x = x

one = MyClass4()
two = MyClass4()


print(id(one) == id(two))

 

你可能感兴趣的:(python)