多种方法实现单例模式 pickle模块
阅读原文时间:2023年07月08日阅读:2

目录

单例模式

比如系统调用打印机,不管你要打印几次,都是调用同一个打印机。这时候多个打印任务,就都用的是一个打印机对象。

class C1:
    __instance = None

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

    @classmethod
    def singleton(cls):
        if not cls.__instance:
            cls.__instance = cls('jason', 18)
        return cls.__instance

obj1 = C1.singleton()
obj2 = C1.singleton()
obj3 = C1.singleton()
print(id(obj1), id(obj2), id(obj3))
obj4 = C1('kevin', 28)
obj5 = C1('tony', 38)
print(id(obj4), id(obj5))


class Mymeta(type):
    def __init__(self, name, bases, dic):  # 定义类Mysql时就触发
        # 事先先从配置文件中取配置来造一个Mysql的实例出来
        self.__instance = object.__new__(self)  # 产生对象
        self.__init__(self.__instance, 'jason', 18)  # 初始化对象
        # 上述两步可以合成下面一步
        # self.__instance=super().__call__(*args,**kwargs)
        super().__init__(name, bases, dic)

    def __call__(self, *args, **kwargs):  # Mysql(...)时触发
        if args or kwargs:  # args或kwargs内有值
            obj = object.__new__(self)
            self.__init__(obj, *args, **kwargs)
            return obj
        return self.__instance

class Mysql(metaclass=Mymeta):
    def __init__(self, name, age):
        self.name = name
        self.age = age

obj1 = Mysql()
obj2 = Mysql()
print(id(obj1), id(obj2))
obj3 = Mysql('tony', 321)
obj4 = Mysql('kevin', 222)
print(id(obj3), id(obj4))

python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。

'''基于模块的单例模式:提前产生一个对象 之后导模块使用'''
class C1:
    def __init__(self, name):
        self.name = name

obj = C1('jason') # 大家快来导我


def outer(cls):
    _instance = cls('jason', 18)
    def inner(*args, **kwargs):
        if args or kwargs:
            obj = cls(*args, **kwargs)
            return obj
        return _instance

    return inner

@outer  # Mysql=outer(Mysql)
class Mysql:
    def __init__(self, host, port):
        self.host = host
        self.port = port

obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(obj1 is obj2 is obj3)  # True

obj4 = Mysql('1.1.1.3', 3307)
obj5 = Mysql('1.1.1.4', 3308)
print(obj3 is obj4)  # False


class Single(type):
    def __call__(cls, *args, **kwargs):
        if hasattr(cls, 'single'):
            return cls.single
        cls.single = super(Single, cls).__call__(*args, **kwargs)
        return cls.single

class A(metaclass=Single):
    def __init__(self, name):
        self.name = name

pickle序列化模块

  1. 可序列化python中所有的类型

  2. 只能在python中使用 无法跨语言传输

  3. 用二进制来保存对象

  4. 用哪个py文件保存 就在哪个文件读取 用别的py文件读文件中的对象 会报错

  5. 读取文件中的对象时,确保产生对象的类体代码也在当前py文件中。才能把对象原封不动的交给你。

    pickle的使用和json模块类似。都有dump\load方法,传参顺序也是相同的。
    优势:能够序列化python中所有的类型
    缺陷:只能够在python中使用 无法跨语言传输
    """
    需求:产生一个对象并保存到文件中 取出来还是一个对象
    """
    class C1:
    def init(self, name, age):
    self.name = name
    self.age = age

    def func1(self):
        print('from func1')
    
    def func2(self):
        print('from func2')

    obj = C1('jason', 18)

    import json

    with open(r'a.txt','w',encoding='utf8') as f:

    json.dump(obj, f)

    import pickle

    with open(r'a.txt', 'wb') as f:

    pickle.dump(obj, f)

    with open(r'a.txt','rb') as f:

    data = pickle.load(f)

    print(data)

    data.func1()

    data.func2()

    print(data.name)

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章