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