Python: украсить класс, указав декоратор как класс
Может ли кто-нибудь показать простой пример этого? Я пытаюсь достичь того, что было реализовано в Python 2.6, используя PEP 3129, за исключением того, что классы не функционируют, как объясняет Брюс Эккель здесь
Следующие работы:
class Decorator(object):
def __init__(self, arg):
self.arg = arg
def __call__(self, cls):
def wrappedClass(*args):
return cls(*args)
return type("TestClass", (cls,), dict(newMethod=self.newMethod, classattr=self.arg))
def newMethod(self, value):
return value * 2
@Decorator("decorated class")
class TestClass(object):
def __init__(self):
self.name = "TestClass"
print "init %s"%self.name
def TestMethodInTestClass(self):
print "test method in test class"
def newMethod(self, value):
return value * 3
Кроме того, в приведенном выше примере wrappedClass не является классом, а функцией, управляемой для возврата типа класса. Я хотел бы написать то же, что можно назвать следующим:
def __call__(self, cls):
class wrappedClass(cls):
def __init__(self):
... some code here ...
return wrappedClass
Как это сделать?
РЕДАКТИРОВАТЬ: я не совсем уверен, что происходит в ""... здесь есть код... "" "
Ответы
Ответ 1
Если вы хотите перезаписать new_method()
, просто сделайте это:
class Decorator(object):
def __init__(self, arg):
self.arg = arg
def __call__(self, cls):
class Wrapped(cls):
classattr = self.arg
def new_method(self, value):
return value * 2
return Wrapped
@Decorator("decorated class")
class TestClass(object):
def new_method(self, value):
return value * 3
Если вы не хотите изменять __init__()
, вам не нужно перезаписывать его.
Ответ 2
После этого класс NormalClass становится экземпляром класса экземпляра класса :
def decorator(decor_arg):
class ClassWrapper:
def __init__(self, cls):
self.other_class = cls
def __call__(self,*cls_ars):
other = self.other_class(*cls_ars)
other.field += decor_arg
return ClassWrapper
@decorator(" is now decorated.")
class NormalClass:
def __init__(self, name):
self.field = name
def __repr__(self):
return str(self.field)
Тест:
if __name__ == "__main__":
A = NormalClass('A');
B = NormalClass('B');
print A
print B
print NormalClass.__class__
Вывод:
A теперь украшено.
B теперь украшен.
__main __. classWrapper