• 33.python中的单例模式


    1. 装饰器函数实现单例设计模式

    def singleton(cls):
        instances = {}
        def get_instance(*args, **kwargs):
            if cls not in instances:
                instances[cls] = cls(*args, **kwargs)
            return instances[cls]
        return get_instance
    @singleton
    class Order:
        def __init__(self, title, price):
            self.title = title
            self.price = price
        def save(self):
            print(f'保存订单{self.title}成功!')
    @singleton
    class OrderInfo:
        def __init__(self, order_id, good_id):
            self.order_id = order_id
            self.goods_id = good_id
        def save(self):
            print(f'保存订单{self.order_id}的详情{self.goods_id}成功!')
    def save(*args):
        for obj in args:
            obj.save()
    if __name__ == '__main__':
        o1 = Order('Phone7', 9000)
        o2 = Order('Lenvon 9000', 4500)
        oi1 = OrderInfo(1, '1110000')
        oi2 = OrderInfo(1, '1130000')
        save(o1, o2, oi1, oi2)
    

    2. 基类方式实现单例设计

    import json
    import pickle
    class Singleton:
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls, '_instance'):
                cls._instance = super().__new__(cls, *args, **kwargs)
                cls._instance.sets = {}  # 单例的字典数据对象属性
            return cls._instance
    class SingletonHashSet(Singleton):
    
        def add(self, key, value):
            self.sets[key] = value
        def exists(self, key):
            return key in self.sets
        def get(self, key):
            if key not in self.sets:
                raise KeyError(f'{key} not exisits')
            return self.sets[key]
        def remove(self, key):
            if self.exists(key):
                del self.sets[key]
        def __str__(self):
            return json.dumps(self.sets)
        
        @classmethod
        def get_instance(cls):
            if not hasattr("cls", "_instance"):
                cls._instance = super().__new__(cls, *args, **kwargs)
            return cls._instance
        
    if __name__ == '__main__':
        app = SingletonHashSet()
        app.add('name', 'disen')
        app.add('age', 20)
        print(app)
        app2 = SingletonHashSet()
        app2.add('name2', 'jack')
        app2.add('age2', 18)
        print(app2)
    

    基于元类实现:

    class Method_(type):
        def __init__(self, *args, **kwargs):
            super(Method_, self).__init__(*args, **kwargs)
    
        def __call__(cls, *args, **kwargs):
            # 2.这里的cls其实就是Foo类对象
            if not hasattr(cls, "_instance"):
                # 3.通过调用自己的__new__方法生成实例对象
                cls._instance = cls.__new__(cls, *args, **kwargs)
            else:
                cls._instance = getattr(cls, "_instance")
            cls.__init__(cls._instance, *args, **kwargs)  # 必须使用,否则属性无法加载
            return cls._instance
    
    
    class Foo(metaclass=Method_):
        def __init__(self, name):
            self.name = name
    
        def __new__(cls, *args, **kwargs):
            return object.__new__(cls)
    
    
    f = Foo("xlex")  # 1.类名加()等同于执行元类中的__call__方法
    print(f.name)
    f2 = Foo("alex")
    print(f2.name)
    

    通过__new__方法:

    class Foo(object):
        def __init__(self, name):
            self.name = name
    
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls, "_instance"):
                cls._instance = object.__new__(cls)
                return cls._instance
            return getattr(cls, "_instance")
    
    
    f = Foo("xlex")
    print(id(f))
    print(f.name)
    f2 = Foo("alex")
    print(id(f2))
    
    print(f2.name)
    
  • 相关阅读:
    D. The Fair Nut and the Best Path 树形dp (终于会了)
    (二)网络流之最大流
    网络流(知识点) 一 终究还是躲不掉
    dp 优化 F2. Pictures with Kittens (hard version)
    da shu mo ban
    AtCoder Regular Contest 090 F
    Codeforces 918D MADMAX 图上dp 组合游戏
    Codeforces 918C The Monster
    AtCoder Regular Contest 090 C D E F
    poj 3623 Best Cow Line, Gold 后缀数组 + 贪心
  • 原文地址:https://www.cnblogs.com/liuzhanghao/p/12679676.html
Copyright © 2020-2023  润新知