将Singleton实现为元类,但用于抽象类 [英] Implementing Singleton as metaclass, but for abstract classes
本文介绍了将Singleton实现为元类,但用于抽象类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个抽象类,我想为从我的抽象类继承的所有类实现Singleton模式.我知道我的代码将无法正常工作,因为将存在元类属性冲突.有什么想法可以解决这个问题吗?
I have an abstract class and I would like to implement Singleton pattern for all classes that inherit from my abstract class. I know that my code won't work because there will be metaclass attribute conflict. Any ideas how to solve this?
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__
方法,因此添加一个是安全的.
Metaclasses work just like regular classes; you can still create subclasses and extend their functionality. ABCMeta
doesn't itself define a __call__
method, so it is safe to add one.
演示:
>>> 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
这篇关于将Singleton实现为元类,但用于抽象类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文