我有一个装饰器,一个装饰器装饰的类和一个子类:
def decorated_by_function(cls):
return cls
@decorated_by_function
class F(object):
pass
class G(F):
pass
没问题。
现在,我将装饰器的实现更改为基于类:
class decorated_by_class(object):
def __init__(self, cls):
self._cls = cls
def __call__(self, *args, **kwargs):
return self._cls(*args, **kwargs)
@decorated_by_class
class C(object):
pass
class D(C):
pass
Python给出了这个错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "h.py", line 23, in <module>
class D(C):
TypeError: Error when calling the metaclass bases
__init__() takes exactly 2 arguments (4 given)
编辑:
@donkopotamus在下面给出了部分答案,C
是一个实例而不是一个类。这就是为什么C
不能被子类化的原因。我明白那个。我的问题是:是否可以保留基于类的方法,同时还允许将装饰类子类化?
使用类的优点是可以扩展。想象一下具有更复杂逻辑的装饰器。什么是修改其某些行为的自然方式,但保留了大部分逻辑?使用基于类的方法使得具有略微不同功能的类似装饰器的树。这就是我想研究这种可能性的原因。
答案 0 :(得分:0)
在这种情况下
@decorated_by_class
class C(object):
pass
大致相当于:
class C(object):
pass
C = decorated_by_class(C)
因此,在这种情况下,C
现在是类decorated_by_class
的实例 ...它本身不是类。因此,您无法创建从D
继承的另一个类C
。
我相信您可能真正想做的是使用类的实例作为装饰器,例如:
class decorated_by_class(object):
def __init__(self, *some_decorator_args):
self.args = some_decorator_args
def compute_something(self):
return self.args
def __call__(self, cls):
# do something with the class
cls.decorated_with_args = self.compute_something()
return cls
@decorated_by_class("hello")
class C(object):
pass
print(C.decorated_with_args) # => ('hello',)
class decorated_by_subclass(decorated_by_class):
def compute_something(self):
return self.args * 2
@decorated_by_subclass("hello")
class D(object):
pass
print(D.decorated_with_args) # => ('hello', 'hello')