单例模式
- 单例模式:基于某种方法实例化多次得到实例是同一个
- 当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例
- 减少内存占用
类内部定义静态方法实现单例模式
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