18 Dec. 2009
This produces the following output:
Classes as Decorators of Methods
-----Parsing dec
-----Parsing C
----- dec init
type 'function'
decorated method: run
-----Object creation
-----Object method call
-----dec get
-----dec call
class '__main__.dec'
class '__main__.C'
type 'type'
THIS IS A DECORATOR Hello world
--- Parsing dec
--- Parsing foo
--- Run dec
(3,)
--- Calling foo
--- Run x
foo
(1,)
{}
--- Run foo
1 3
--- Calling foo
--- Run x
foo
(2, 4)
{}
--- Run foo
2 4
comments powered by Disqus
Classes as Decorators of Methods in Python
I have had some trouble to figure out how to use a class as a decorator for a method (as opposed to a decorator for a function). Here is a script that prints some useful information about what is called when and with what parameters.
#!/usr/bin/env python print "Classes as Decorators of Methods\n" print "-----Parsing dec" class dec(object): def __init__(self, a): print "----- dec init" print type(a) print "decorated method: ", a.__name__ self.a = a def __get__(self, inst, cls): print "-----dec get" self._inst = inst self._cls = cls return self def __call__(self, p): print "-----dec call" print type(self) print type(self._inst) print type(self._cls) return self.a(self._inst, p.upper()) print "-----Parsing C" class C(object): def __init__(self): self.X = "Hello" @dec def run(self, p): print p, print self.X, return "world" if __name__ == "__main__": print "-----Object creation" c = C() print "-----Object method call" print c.run("This is a decorator ")
This produces the following output:
Classes as Decorators of Methods
-----Parsing dec
-----Parsing C
----- dec init
type 'function'
decorated method: run
-----Object creation
-----Object method call
-----dec get
-----dec call
class '__main__.dec'
class '__main__.C'
type 'type'
THIS IS A DECORATOR Hello world
In contrast: functions as decorators for functions
#!/usr/bin/env python print "--- Parsing dec" def dec(f): print "--- Run dec" print f.__defaults__ def x(*args, **kwargs): print "--- Run x" print f.__name__ print args print kwargs f(*args, **kwargs) return x print "--- Parsing foo" @dec def foo(a, b=3): print "--- Run foo" print a, b print "--- Calling foo" foo(1) print "--- Calling foo" foo(2, 4)Which outputs:
--- Parsing dec
--- Parsing foo
--- Run dec
(3,)
--- Calling foo
--- Run x
foo
(1,)
{}
--- Run foo
1 3
--- Calling foo
--- Run x
foo
(2, 4)
{}
--- Run foo
2 4