单例模式与pickle模块
设计模式之单例模式
设计模式是前辈们发明的经过反复验证用于解决固定问题的固定套路,在IT行业中设计模式总共有23种,可以分为三大类:创建型、结构型、行为型。这里不做详细的讲解。
单例模式
单例模式是设计模式中的其中一种,目的是让多次实例化结果指向同一个实例,简单的来说就是让一个类只能产生一个对象,用于节省资源。
比如此时我有一个类了,因为我不知道这个类是否已经产生对象了,往往会去在创建一个新对象,这时就有可能造成资源的浪费了。
单例模式有多种编写方式,这里只写出部分编写方式:
1.基于@classmethod
class MyClass(object):
obj = None
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def singleton(cls, name, age):
if not cls.obj:
cls.obj = cls(name, age)
return cls.obj
obj1 = MyClass.singleton('tom', 18)
obj2 = MyClass.singleton('jack', 28)
print(obj1.__dict__) # 输出:{'name': 'tom', 'age': 18}
print(obj2.__dict__) # 输出:{'name': 'tom', 'age': 18}
print(obj1 is obj2) # 输出:True
2.基于装饰器
def singleton(cls):
obj = None
def inner(*args, **kwargs):
nonlocal obj
if obj:
return obj
obj = cls(*args, **kwargs)
return obj
return inner
@singleton
class MyClass:
def __init__(self, name, age):
self.name = name
self.age = age
obj1 = MyClass('tom', 18)
obj2 = MyClass('jack', 28)
print(obj1.__dict__) # 输出:{'name': 'tom', 'age': 18}
print(obj2.__dict__) # 输出:{'name': 'tom', 'age': 18}
print(obj1 is obj2) # 输出:True
3.基于元类
class Mymeta(type):
def __call__(cls, *args, **kwargs):
if cls.obj:
return cls.obj
obj = super().__call__(*args, **kwargs)
cls.obj = obj
return obj
class MyClass(metaclass=Mymeta):
# 用来确认是否创建过对象
obj = None
def __init__(self, name, age):
self.name = name
self.age = age
obj1 = MyClass('tom', 18)
obj2 = MyClass('jack', 28)
print(obj1.__dict__) # 输出:{'name': 'tom', 'age': 18}
print(obj2.__dict__) # 输出:{'name': 'tom', 'age': 18}
print(obj1 is obj2) # 输出:True
4.基于__new__
class MyClass(object):
obj = None
def __init__(self, name, age):
self.name = name
self.age = age
def __new__(cls, *args, **kwargs):
if not cls.obj:
cls.obj = object.__new__(cls)
return cls.obj
obj1 = MyClass('tom', 18)
obj2 = MyClass('jack', 28)
print(obj1.__dict__) # 输出:{'name': 'jack', 'age': 28}
print(obj2.__dict__) # 输出:{'name': 'jack', 'age': 28}
print(obj1 is obj2) # 输出:True
5.基于模块
# 单独在一个py文件中定义一个类,并实例化一个对象,之后在其他文件导入这一对象,实现单例
class Singleton(object):
def __init__(self,host,port):
self.host = host
self.port = port
# 之后都导入这个对象即可
singleton = Singleton('127.0.0.1',3306)
实现单例模式的方式不固定,方式有很多,这里只列出其中的几种。
pickle模块
pickle模块基本不会去被使用,兼容性太差,一般都使用ORM替代pickle。
pickle模块可以将对象保存到文件中,并且可以取出后继续使用。
将对象保存到文件中:
import pickle
class MyClass(object):
def __init__(self, name):
self.name = name
def eat(self):
print('%s正在干饭' % self.name)
obj = MyClass('tom')
# 将对象存到文件中
with open(r'%s' % obj.name, 'wb') as f:
pickle.dump(obj, f)
从文件中获取对象:
import pickle
class MyClass(object):
def __init__(self, name):
self.name = name
def eat(self):
print('%s正在干饭' % self.name)
# 将对象从文件中取出来
with open(r'tom', 'rb') as f:
obj = pickle.load(f)
print(obj) # 输出:<__main__.MyClass object at 0x00000183EC49CFD0>
print(obj.name) # 输出:tom
obj.eat() # 输出:tom正在干饭