On Apr 2, 10:31 am, George Sakkis <[EMAIL PROTECTED]> wrote: > 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- Hide quoted text - > > - Show quoted text -
Thanks George, that was helpful. I guess my real question is: why does wrapping the call to be "call=lambda x: DecorateMe.callMe(x)" somehow fix the issue with this temporary namespace? It seems strange to me that defining an additional function (through lambda) would allow me to see/add more members to the namespace. -- http://mail.python.org/mailman/listinfo/python-list