day24-2 单例模式

单例模式

  • 单例模式:基于某种方法实例化多次得到实例是同一个
  • 当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例
  • 减少内存占用

类内部定义静态方法实现单例模式

NAME = 'nick'
AGE = 18

class Foo():
    __instance = None
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    @classmethod
    def eat(cls):
        if not cls.__instance:
            cls.__instance = cls(NAME, AGE)
        return cls.__instance

obj1 = Foo.eat()
obj2 = Foo.eat()
obj3 = Foo.eat()
print(obj1 is obj2 is obj3)  # 实例化多次得到同一个实例
True
obj4 = Foo('tank',19)
print(obj1.__dict__)
print(obj4.__dict__)
{'name': 'nick', 'age': 18}
{'name': 'tank', 'age': 19}

装饰器实现单例模式

NAME = 'nick'
AGE = 18

def deco(cls):
    cls.__instance = cls(NAME, AGE)
    def wrapper(*args, **kwargs):
        if len(args) == 0 and len(kwargs) == 0:
            return cls.__instance
        return cls(*args, **kwargs)
    return wrapper
    
@deco
class Foo:
    def __init__(self, name, age):
        self.name = name
        self.age = age 
        
f = Foo()
print(f.__dict__)
f1 = Foo()
print(f1.__dict__)
print(f == f1)
print("*" * 50)
f2 = Foo('tank', 19)
print(f2.__dict__)
print(f == f2)
{'name': 'nick', 'age': 18}
{'name': 'nick', 'age': 18}
True
**************************************************
{'name': 'tank', 'age': 19}
False

元类实现单例模式

NAME = 'nick'
AGE = 18

class Mymeta(type):
    def __init__(self, class_name, class_bases, class_dic):
        super(Mymeta, self).__init__(class_name, class_bases,class_dic)
        
        self.__instance = self(NAME, AGE)
        
    def __call__(self, *args, **kwargs):
        if len(args) == 0 and len(kwargs) == 0:
            return self.__instance
        obj = self.__new__(self)
        self.__init__(obj,*args, **kwargs)
        return obj
        
class Foo(object,metaclass=Mymeta):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
f = Foo()
print(f.__dict__)
f1 = Foo()
print(f1.__dict__)
print(f == f1)
print("*" * 50)
f2 = Foo('tank', 19)
print(f2.__dict__)
print(f == f2)
{'name': 'nick', 'age': 18}
{'name': 'nick', 'age': 18}
True
**************************************************
{'name': 'tank', 'age': 19}
False
posted @ 2019-06-25 17:08  Never&say&die  阅读(111)  评论(0编辑  收藏  举报