如何在Python单元测试中删除单例实例装饰器?

3 投票
1 回答
5195 浏览
提问于 2025-04-18 13:40

我刚开始学习Python。我定义了一个单例装饰器,代码如下:

def singleton(cls):
    instances = {}

    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

还有我的单例类,代码是:

@singleton
class MyClass:

    def __init__(self, **kwargs):
        self.config = None
        ...

我想为MyClass写一些单元测试,但我需要在tearDown()方法中销毁它,这样测试才能正常运行。我该怎么做呢?

非常感谢!

1 个回答

2

我觉得这个问题可以换个说法,就是“我能在闭包外部访问闭包里的变量吗”,这样可以更清楚地理解`instances`字典。

我还没有测试过这个方法,但这个思路可能有效,就是把实例数据作为一个函数的属性暴露出来(基本上就是把它当成模块级别的变量)。

def singleton(cls):

    def getinstance():
        if cls not in singleton.instances:
            singleton.instances[cls] = cls()
        return singleton.instances[cls]
    return getinstance

singleton.instances = {}


# Then clear
def tearDown(self):
    singleton.instances = {}

不过我不太确定你是否想为了实现单例模式而走这么多弯路。例如,还有一种替代的方法,比较简单,不那么复杂的懒加载模式可以是:

class MyClass:

     @classmethod
     def get_instance(cls):
         if not hasattr(cls, "_instance"):
             cls._instance = cls()
         return cls._instance

instance = MyClass.get_instance()

或者更简单一点,不用懒加载:

class MyClass:
    ...


MyClass.instance = MyClass()

撰写回答