Vanson's Eternal Blog

Python中常用到的设计模式

Python design pattern.png
Published on
/3 mins read/---

Python中的设计模式

设计模式有助于写出更简洁优雅的代码,防止系统架构不断腐化。

单例模式

__new__方法

"""
1. 定义一个类变量 _instance 来存储唯一的实例。
2. 重写类的 __new__ 方法,确保每次调用时只创建一个实例。
3. 第一次初始化 类变量 _instance。 
"""
class Singleton:
    _instance = None
 
    def __new__(cls):
        if cls._instance is None:
            # 调用父类(即 object 类)的 __new__ 方法来创建一个新的实例。
            class._instance = super(Singleton, cls).__new__(cls)
        return cls._instance
 
# 用例
s1 = Singleton()
s2 = Singleton()
 
print(s1 is s2)  # 输出: True
 

threading.Lock 实现线程安全

第一种的线程安全版

import threading
 
""" 
1. 定义一个类变量 _instance
2. 定义锁 _lock
3. 重写__new__方法
4. 获取锁了在创建实例
"""
class Singleton:
    _instance = None
    _lock = threading.Lock()
 
    def __new__(cls):
        with cls._lock:
            if cls._instance is None:
                cls._instance = super(Singleton, clas).__new__(cls)
        return _instance
 
# 用例
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # 输出: True
 

不支持多线程,如果需要支持多线程,需要额外的线程安全措施。

使用元类

元类(metaclass)是类的类,可以控制类的创建过程。通过元类实现单例模式,可以更灵活地控制实例的创建。

"""
1. 定义一个元类 SingletonMeta,该元类继承自 type。
2. 定义_instances。
3. 创建实例并存入_instances。
"""
 
class SingletonMeta(type):
    _instances = {}
 
    def __call__(cls, *arg, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(SingletonMeta, cls).__call__(*arg, **kwargs)
            return cls._instances[cls]
 
class Singleton(metaclass=SingletonMeta):
    pass
 
# 用例
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # 输出: True
 

functools.lru_cache

"""
1. 定义1个业务类。
2. 定义缓存函数get_singleton
3. 使用 functools.lru_cache 装饰器来缓存函数的返回值。设置 maxsize=1,确保函数只返回一个实例。
4. 通过函数获取单实例
"""
import functools
 
@functools.lru_cache(maxsize=1)
def get_singleton():
    return MyClass()
 
class MyClass:
    pass
 
# 用例
s1 = get_singleton()
s2 = get_singleton()
print(s1 is s2)  # 输出: True