如何以正确的方式装饰一个类,以便能够从被装饰的类继承一个类?有没有正确的方法?
如果我会做这样的事情:
def singleton(cls):
inst = {}
def get(*args, **kwargs):
cls_id = id(cls)
if cls_id not in inst:
inst[cls_id] = cls(*args, **kwargs)
return inst[cls_id]
return get
@singleton
class A(object):
@classmethod
def cls_meth(cls):
return cls
我没有机会从上面的类继承一个类,因为在我调用它之前这是函数。 classmethods同样的问题,function没有classmethods。
class B(A): # No way! `A` is the function!
pass
A.cls_meth() # AttributeError: 'function' object has no attribute 'cls_meth'
即使我在做类似的事情:
class SingletonDecorator(object):
inst = {}
def __init__(self, cls):
self.cls = cls
def __call__(self, *args, **kwargs):
cls_id = id(self.cls)
if cls_id not in self.inst:
self.inst[cls_id] = self.cls(*args, **kwargs)
return self.inst[cls_id]
@SingletonDecorator
class A(object):
pass
当我从A类继承一个类时,它将从SingletonDecorator类而不是A继承。
class B(A): # No no no! I do not need a `SingletonDecorator` child class...
pass
有一种方法可以通过 __metaclass__ 修改类实例,但这绝对是另一回事...
请您参考如下方法:
您的装饰器需要返回原始类(或其子类)才能进一步子类化。您的装饰器在用作装饰器时返回其自身的一个实例(因为这是调用类的默认行为)。
例如,像这样:
def singleton(cls):
class C(cls):
_instance = None
def __new__(c, *args, **kwargs):
if type(c._instance) != c:
c._instance = cls.__new__(c, *args, **kwargs)
return c._instance
C.__name__ = cls.__name__
return C
这将返回原始类的一个子类,该子类具有重写的 __new__() 方法,该方法执行单例魔术。这个类是可继承的。
然而,几乎没有任何理由创建单例。通常它只是一种隐藏全局状态的方法,最好将其消除。
