python - 将 Singleton 实现为元类,但用于抽象类

标签 python singleton abstract-class metaclass abc

我有一个抽象类,我想为所有从我的抽象类继承的类实现单例模式。我知道我的代码不会工作,因为会有元类属性冲突。有什么解决办法吗?

from abc import ABCMeta, abstractmethod, abstractproperty

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class GenericLogger(object):
    __metaclass__ = ABCMeta

    @abstractproperty
    def SearchLink(self): pass

class Logger(GenericLogger):
    __metaclass__ = Singleton

    @property
    def SearchLink(self): return ''

a = Logger()

最佳答案

创建 ABCMeta 的子类:

class SingletonABCMeta(ABCMeta):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(SingletonABCMeta, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class GenericLogger(object):
    __metaclass__ = SingletonABCMeta

    @abstractproperty
    def SearchLink(self): pass


class Logger(GenericLogger):  
    @property
    def SearchLink(self): return ''

元类就像普通类一样工作;您仍然可以创建子类并扩展它们的功能。 ABCMeta 本身没有定义 __call__ 方法,因此添加一个是安全的。

演示:

>>> from abc import ABCMeta, abstractproperty
>>> class SingletonABCMeta(ABCMeta):
...     _instances = {}
...     def __call__(cls, *args, **kwargs):
...         if cls not in cls._instances:
...             cls._instances[cls] = super(SingletonABCMeta, cls).__call__(*args, **kwargs)
...         return cls._instances[cls]
...
>>> class GenericLogger(object):
...     __metaclass__ = SingletonABCMeta
...     @abstractproperty
...     def SearchLink(self): pass
...
>>> class Logger(GenericLogger):
...     @property
...     def SearchLink(self): return ''
...
>>> Logger()
<__main__.Logger object at 0x1012ace90>
>>> Logger()
<__main__.Logger object at 0x1012ace90>
>>> class IncompleteLogger(GenericLogger):
...     pass
...
>>> IncompleteLogger()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __call__
TypeError: Can't instantiate abstract class IncompleteLogger with abstract methods SearchLink

关于python - 将 Singleton 实现为元类,但用于抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33364070/

相关文章:

python - BeautifulSoup:在每个标题后获取所有 <ul> 的所有内容

python - 随机播放按行聚合的列表字典

c++ - C++ 中的全局变量

multithreading - 在 Scala 上创建线程本地对象

java - 抽象类的复制构造函数

c++ - 如果抽象基类是一个接口(interface),是否必须在派生类构造函数中调用基类构造函数?

java - Netty:绑定(bind)不匹配

python - 使用 SMOTE 时验证集性能不佳

python - 大文本文件的并行计算

Objective-C:什么时候知道你在滥用全局变量的 SIngleton 方法