您现在的位置是:网站首页 > 博客日记 >

python创建类设计模式|单例模式

作者:YXN-python 阅读量:53 发布日期:2024-12-11

1、模块

# myclass.py
class MyClass:
    obj = None

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

obj = MyClass('Alice', 25)

# temp.py
from myclass import obj
from myclass import obj

2、类装饰器

def singleton(cls):
    instances = {}

    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        cls.__init__(instances[cls], *args, **kwargs)  # 根据需求是否需要重新初始化
        return instances[cls]

    return get_instance


@singleton
class MyClass:
    def __init__(self, name, age):
        self.name = name
        self.age = age


obj = MyClass('Alice', 25)
obj2 = MyClass('Alice', 65)
print(obj)  
print(obj2)   # 输出结果相同,说明obj和obj2是同一个实例

3、类绑定方法

class MyClass:
    obj = None

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

    @classmethod
    def get_obj(cls, *args, **kwargs):
        if not cls.obj:
            cls.obj = cls(*args, **kwargs)
        return cls.obj


obj = MyClass.get_obj('Alice', 25)
obj2 = MyClass.get_obj('Alice', 65)
print(obj)
print(obj2)  # 输出结果相同,说明obj和obj2是同一个实例

4、__new__方法

class MyClass:
    obj = None

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

    def __new__(cls, *args, **kwargs):
        if not cls.obj:
            cls.obj = super().__new__(cls)
        return cls.obj


obj = MyClass('Alice', 25)
obj2 = MyClass('Alice', 65)
print(obj)
print(obj2)  # 输出结果相同,说明obj和obj2是同一个实例

5、元类

class MyType(type):
    obj = None

    def __call__(self, *args, **kwargs):
        if not self.obj:
            # self.obj = super().__call__(*args, **kwargs)  # 或者下面两行
            self.obj = self.__new__(self)
        self.__init__(self.obj, *args, **kwargs)  # 根据需求看要不要放上面的判断里面
        return self.obj

# 或者
class MyType2(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            # cls._instances[cls] = super().__call__(*args, **kwargs)  # 或者下面两行
            cls._instances[cls] = cls.__new__(cls)
        cls.__init__(cls._instances[cls], *args, **kwargs)  # 根据需求看要不要放上面的判断里面
        return cls._instances[cls]

class MyClass(metaclass=MyType):
    obj = None

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


obj = MyClass('Alice', 25)
print(obj, obj.__dict__)  # <__main__.MyClass object at 0x00000235EB679130> {'name': 'Alice', 'age': 25}
obj2 = MyClass('Alice', 65)
print(obj2, obj2.__dict__)  # <__main__.MyClass object at 0x00000235EB679130> {'name': 'Alice', 'age': 65}

再度优化

...
# 其他代码已省略
class Singleton(metaclass=MyType):
    pass

class MyClass(Singleton):
    ...

6、并发

import threading

class MyClass:
    _instance = None
    _lock = threading.Lock()
    
    def __new__(cls):
        with cls._lock:
            if cls._instance is None:
                cls._instance = super().__new__(cls)
        return cls._instance

obj = MyClass()
print(obj) 
obj2 = MyClass()
print(obj2)

 

YXN-python

2024-12-11