On Apr 2, 8:30 am, Thomas Dimson <[EMAIL PROTECTED]> wrote: > Hello, > > Originally I posted this as a bug but it was shot down pretty quickly. > I am still mildly curious about this as I'm missing a bit of > understanding of Python here. Why is it that the following code > snippet: > > def decorator( call ): > def inner(func): > def application( *args, **kwargs ): > call(*args,**kwargs) > func(*args,**kwargs) > return application > > return inner > > class DecorateMe: > @decorator( call=DecorateMe.callMe ) > def youBet( self ): > pass > > def callMe( self ): > print "Hello!" > > DecorateMe().youBet() > > Will not compile, giving: > Traceback (most recent call last): > File "badpython.py", line 10, in <module> > class DecorateMe: > File "badpython.py", line 11, in DecorateMe > @decorator( call=DecorateMe.callMe ) > NameError: name 'DecorateMe' is not defined > > Where if you change the "call=DecorateMe.callMe" to "call=lambda x: > DecorateMe.callMe(x)" everything goes along its merry way. Nesting the > call in a lambda seems to allow it to recognize the class definition. > Any ideas as to what is going on here (other than ugly code)?
The error message is pretty obvious; when the "@decorator(call=DecorateMe.callMe)" line is reached, the DecorateMe class has not been created yet, let alone the DecorateMe.callMe method. One way to make it work (for some definition of "work" ;-) is the following: # use "new-style" classes unless you have a good reason not to: # class DecorateMe(object): class DecorateMe: def callMe(self): print "Hello!" @decorator(call=callMe) def youBet(self): pass The reason this works is that at the point where @decorator is executed, callMe is already in the temporary namespace to be used for creating the DecorateMe class (although the class itself is not built yet). A subtle point is that in this case callMe is a plain function, not an (unbound) method such as DecorateMe.callMe. This may or may not matter, depending on what you do with it in the decorator. Some decorators that work fine with plain functions break if they are used to decorate methods (or vice versa) so it's good to have this in mind when writing or debugging a decorator. George -- http://mail.python.org/mailman/listinfo/python-list