首页 > 解决方案 > Define number of uses in a decorator (Singleton pattern with decorators)

问题描述

I'm trying to implement a Singleton design pattern with using decorators. It can be easily achieved using metaclasses but the problem I've faced with is that a class can have more than 1 pattern.

For example, a class can be both an observer or a singleton. My decorator looks like this:

def Singleton(_cls):
    _instances = {}

    def wrapper(*args, **kwargs):
        if _cls not in _instances:
            _instances[_cls] = object.__new__(_cls)
            _instances[_cls].__dict__.update(kwargs)
        else:
            raise AlreadyDefinedError(
                "A Singleton instance has been defined already. "
                "You can't have more than 1 Singleton object."
            )

        return _instances[_cls]

    return wrapper

The problem is, since Singleton is a function, this code doesn't work for it. Every time I decorate a new class, my _instances dict is re-defined and it's empty. Are there any ways of solving this problem?

标签: python

解决方案


你还没有更新*args你的字典。

有很多方法可以做一个单例装饰器。这是一种功能属性方法。

import functools as ft

def singleton(cls):
    @ft.wraps(cls)
    def wrapper(*args, **kwargs):
        if wrapper.instance is None:
            wrapper.instance = cls(*args, **kwargs)
        return wrapper.instance
    wrapper.instance = None
    return wrapper

推荐阅读