单例模式与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正在干饭
posted @ 2022-04-12 16:39  Yume_Minami  阅读(37)  评论(0编辑  收藏  举报