自动化测试(三)python-单例模式

137 阅读2分钟

单例模式是设计模式的一种,确保一个类只有一个实例,并提供一个全局访问点。在开发中需要某个类只能有一个实例,比如配置管理、数据库连接池、日志记录之类的场景。

1. 使用模块天然的单例特性

Python 的模块在第一次导入时会执行代码生成对象,之后的导入直接引用已存在的对象,天然支持单例模式。

# singleton.py
class SingletonClass:
    def __init__(self):
        self.value = "单例实例"

singleton_instance = SingletonClass()

# test.py:
from singleton import singleton_instance
print(singleton_instance.value)  # 输出:单例实例

优点:简单、线程安全。
缺点:不够灵活,无法延迟初始化。


2. 使用装饰器

通过装饰器控制类的实例化逻辑,确保只创建一个实例。

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 MyClass:
    def __init__(self, name):
        self.name = name

# 测试
a = MyClass("实例1")
b = MyClass("实例2")
print(a is b)  # 输出:True
print(a.name)   # 输出:实例1(后续初始化参数会被忽略)

优点:代码复用性强,可应用于多个类。
缺点:线程不安全(多线程环境下可能重复创建实例)。如果加锁,则所有被装饰类共享同一个锁对象(不同类的实例化也会互相阻塞)


3. 重写类的 __new__ 方法

通过覆盖类的 __new__ 方法,控制实例的创建过程。

import threading

class ThreadSafeSingleton:
    _instance = None
    _lock = threading.Lock()
    
    def __init__(self):
        pass
        
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            with cls._lock:
                if not cls._instance:
                    cls._instance = super().__new__(cls)
        return cls._instance

# 测试
def create_singleton():
    obj = ThreadSafeSingleton()
    print(id(obj))

threads = [threading.Thread(target=create_singleton) for _ in range(10)]
for t in threads:
    t.start()

缺点__init__会重复执行初始化,可能导致属性被覆盖


  1. 使用元类(Metaclass):通过自定义元类,拦截类的实例化过程。