33. Singleton pattern in python

1. The decorator function implements the singleton design pattern

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. Base class approach to achieve singleton design

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)

Based on metaclass implementation:

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)

Through the __new__ method:

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)

Guess you like

Origin www.cnblogs.com/liuzhanghao/p/12679676.html