Unexpected behaviour of inner functions/ decorators

Scott David Daniels Scott.Daniels at Acm.Org
Tue Jun 30 20:27:09 CEST 2009


Francesco Bochicchio wrote:
> def dec_f(f):
>     def inner_f():
>         if f.enabled:
>            f()
>     return inner_f

> @dec_f
> def funct():
>     print "Ciao"
The three lines above should behave a lot like:
     def funct_original():
         print "Ciao"
     funct = dec_f(funct_original)

 > funct.enabled = True
 > funct()
This is decorating "funct", but inner_f is testing the argument it was
passed (funct_original), not inner_f (which is now called funct).  No
wonder it finds no "enabled" attribute.


 > So I have a workaround, but still don't understant why the original
 > code does not work.
 > Anyone can point me to an explanation?

So, you can fix this like so:
     def dec_f(f):
         def inner_f():
             if inner_f.enabled:
                 f()
         return inner_f

Or even:
     def dec_f(f):
         def inner_f():
             if inner_f.enabled:
                 f()
         inner_f.enabled = False
         return inner_f

Thus testing the thing that you were marking with funct.enabled = True.

Does this help explain?

--Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list