今日讲解之python-实现单例模型的四种方法

今日讲解之python-实现单例模型的四种方法,第1张

今日讲解之python-实现单例模型的四种方法

这是看了林海峰老师讲解单例模型的实现方法的总结来与大家分享~

一、@classmethod ->通过类方法实现

'''class Foo:
    # 定义一个类的数据属性,用于接收对象实例,判断对象是否只有一个
    _instance = None

    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def singlenton(cls, *args, **kwargs):
        # 判断类属性_instance是否有值,有-》代表已经有实例对象
        # 没有则代表没有实例对象,则调用object.__new__获取一个空对象
        if not cls._instance:
            # 没有参数的情况下
            # cls._instance=object.__new__(cls,*args,**kwargs)
            # 有参数的情况下:
            cls._instance = cls(*args, **kwargs)  # 等价于Foo(*args, **kwargs) ->cls==Foo

        # 将已经产生的实例化对象直接返回
        return cls._instance


obj1 = Foo.singlenton('egon', 20)
obj2 = Foo.singlenton('tank', 19)
print(obj1 is obj2)'''

二、元类实现

'''class Mymeta(type):
    def __init__(self,name,base,attrs):# self->Goo
        # 造空对象,然后赋值给Goo类中的_instance类属性
        self._instance=object.__new__(self)
        # 将类名、基类、类的名称空间传给type里面的__init__
        super().__init__(name, base, attrs)

    # 当调用Goo类时,等同于调用元类实例化得到的对象
    def __call__(self, *args, **kwargs):
        # 判断调用Goo时是否传参
        if args or kwargs:
            init_args=args
            init_kwargs=kwargs
        # 1、通过判断限制了用于传入的参数必须一致,然后返回一个实例化对象
            if init_args==args and init_kwargs==kwargs:
                return self._instance
        # 2、若不是一个实例,则创建一个新对象,产生新的内存地址
            obj=object.__new__(self)
            self.__init__(obj,*args, **kwargs)
            return obj
        return self._instance



class Goo(metaclass=Mymeta):# Goo=Mymeta(Goo)

    def __init__(self,x):
        self.x=x
g1=Goo('1')
g2=Goo('2')
print(g1 is g2)'''

三、__new__实现 --》通过调用类方法实例化对象时,自动触发的__new__来实现单例

'''class Aoo:
    _instance=None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance=object.__new__(cls)
        return cls._instance

a1=Aoo()
a2=Aoo()
print(a1 is a2)'''

四、装饰器

'''def singlenton(cls):# cls-->Too
    # 因为装饰器可以给多个类使用所以这里采用字典
    # 以类为key,实例对象作为value值
    _instance={
        # "Too":Too的实例对象
    }
    def inner(*args,**kwargs):
        # 若当前装饰器的类不在字典中,则实例化新类
        if cls not in _instance:
            # obj=cls(*args,**kwargs)
            # return  obj
            # 不在,则给字典添加key为Too,value为Too()-->实例对象
            #{Too:Too(*args,**kwargs)}
            _instance[cls] = cls(*args, *kwargs)
        #return 对应的实例化对象 cls(*args,*kwargs)
        return _instance[cls]
    return inner

@singlenton# -->singlenton(Too)
class Too:
    pass

t1=Too()
t2=Too()
print(t1 is t2)'''

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5624984.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存