What’s the correct syntax?
Programming attempt
class Foo:
def hello(self):
print "Hello cruel world!"
def greet_first(self, f):
self.hello()
return lambda *args, **kwargs: f(*args, **kwargs)
@greet_first
def goodbye(self, concat):
print "Goodbye {0}".format(concat)
if __name__=='__main__':
bar = Foo()
bar.goodbye(' and thanks for all the fish')
Debug
Traceback (most recent call last):
File "prog.py", line 1, in <module>
class Foo:
File "prog.py", line 9, in Foo
@greet_first
TypeError: greet_first() takes exactly 2 arguments (1 given)
A decorator is called immediately, it is not treated as a method of
Foobut rather is seen as a local function instead. The@greet_firstsyntax effectively means:and is executed immediately. It is not a bound method, so the
selfparameter is not included. There is no point in makinggreet_firsta method. Move it out and remove theselfargument altogether.You need to adjust your decorator to return a callable to replace
goodbye:so that
self.hello()is called every timegoodbyeis called.If you have to make
greet_firstpart ofFoo, you can use a@staticmethoddecorator but you have to jump through an extra hoop just to be able to use it for other method declarations; you have to treat it as the descriptor it has become and call.__get__()on it:I call
.__get__()with an arbitrary type (objectin this case) becausestaticmethodignores that argument anyway; we can’t useFoohere because that class has not yet been finalized while inside the code that is part of it’s definition.Note that for
@staticmethodto work at all you need to inherit fromobjectin Python 2.