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

python三种方法创建单例模式

时间:2019-10-24 11:42:16      阅读:64      评论:0      收藏:0      [点我收藏+]

标签:返回   war   let   调用   pre   init   pytho   关系   super   

#  方法一,装饰器
from functools import wraps


def single_instance(cls):
    """装饰器实现单例模式,装饰器相当于把类给包了起来,强制返回一个对象"""
    _instance = None

    @wraps(cls)
    def wrapper(*args, **kwargs):
        nonlocal _instance
        if _instance is None:
            _instance = cls(*args, **kwargs)
        return _instance

    return wrapper


@single_instance
class Test1:
    def __init__(self, name):
        self.name = name
        print("Test init..., name=%s" % self.name)


# 方法二  __new__方法
class Test2:
    _instance = None

    def __init__(self, name):
        self.name = name
        print("Test2 init..., name=%s" % self.name)

    def __new__(cls, *args, **kwargs):
        """__new__主要做的是给实例分配空间,__init__则是在该空间上进行初始化,既然是单例模式,那么空间地址肯定一样,这里做限制"""
        print(__new__, args=, args, ,kwargs=, kwargs)
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance


# 方法三 元类
class SingleType(type):
    """
    普通类相当于是元类的实例,所以在类完成定义时其实是调用元类的__init__方法,而生成类的实例,如 Test(‘AIF‘)则是调用元类的__call__方法
    这个跟普通类和实例的关系其实是一样的。如 t = Test(‘AIF‘), 生成t会调用Test的__init__方法,而t()则会调用Test的__call__方法
    """
    def __init__(self, *args, **kwargs):
        self._instance = None
        super().__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if self._instance is None:
            self._instance = super().__call__(*args, **kwargs)
        return self._instance


class Test3(metaclass=SingleType):
    def __init__(self, name):
        self.name = name
        print("Test3 init..., name=%s" % self.name)


if __name__ == __main__:
    """测试,Test1, Test2, Test3"""
    a = Test3(AIF)
    b = Test3(AIF333)
    print(a=b is %s, id(a)=%s, id(b)=%s % (a is b, id(a), id(b)))
    print(a.name=%s, b.name=%s % (a.name, b.name))

 

python三种方法创建单例模式

标签:返回   war   let   调用   pre   init   pytho   关系   super   

原文地址:https://www.cnblogs.com/yeteng/p/11731059.html

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