What is a simple example of decorating a class by defining the decorator as a class?
I'm trying to achieve what has been implemented in Python 2.6 using PEP 3129 except using classes not functions as Bruce Eckel explains here.
The following works:
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
Except, in the above, wrappedClass is not a class, but a function manipulated to return a class type. I would like to write the same callable as follows:
def __call__(self, cls): class wrappedClass(cls): def __init__(self): ... some code here ... return wrappedClass
How would this be done?
I'm not entirely sure what goes into """... some code here ..."""
A decorator is a design pattern in Python that allows a user to add new functionality to an existing object without modifying its structure. Decorators are usually called before the definition of a function you want to decorate.
Classes as decorators In Python, decorators can be either functions or classes. In both cases, decorating adds functionality to existing functions. When we decorate a function with a class, that function becomes an instance of the class.
You'll use a decorator when you need to change the behavior of a function without modifying the function itself. A few good examples are when you want to add logging, test performance, perform caching, verify permissions, and so on. You can also use one when you need to run the same code on multiple functions.
__call__ in Python The __call__ method enables Python programmers to write classes where the instances behave like functions and can be called like a function. When the instance is called as a function; if this method is defined, x(arg1, arg2, ...) is a shorthand for x.
If you want to overwrite new_method()
, just do it:
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
If you don't want to alter __init__()
, you don't need to overwrite it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With