Unexpected behaviour of inner functions/ decorators

  • Thread starter Francesco Bochicchio
  • Start date
F

Francesco Bochicchio

Hi all,

I found a strange (for me) behaviour of inner function. If I execute
the following code:

# file in_f.py -----------

def dec_f(f):
def inner_f():
if f.enabled:
f()
return inner_f

@dec_f
def funct():
print "Ciao"

funct.enabled = True
funct()

# end of file -----------------


I get the following exception:

File "/Users/fb/Documents/Prove python/in_f.py", line 15, in
<module>
funct()
File "/Users/fb/Documents/Prove python/in_f.py", line 5, in inner_f
if f.enabled:
AttributeError: 'function' object has no attribute 'enabled'


The same happens when I rebind explicitely the function name instead
of using the decorator:

def funct():
print "Ciao"
funct = dec_f(funct)

It looks like the decorator uses an older instance of 'funct', which
does not yet
have the attribute dinamically attached to it. This seem to be
confirmed by the fact that adding the attribute before
rebinding the function name, the problem disappear:

def funct():
print "Ciao"
funct.enabled = False # this fixes the problem
funct = dec_f(funct)

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

Thanks in advance

Ciao
 
D

David Stanek

[snip]

It looks like the decorator uses an older  instance of 'funct', which
does not yet
have the attribute dinamically attached to it. This seem to be
confirmed by the fact that adding the attribute before
rebinding the function name, the problem disappear:

The decorator is using the original function that you defined. By
decorating 'funct' you are actually rebinding that name to the
'inner_f' function. So the statement 'funct.enabled = True' is
actually creating an enabled property on the 'inner_f' function.

Take a look at this code:
.... def inner_f():
.... if iam.enabled:
.... f()
.... iam = inner_f
.... return inner_f
........ def funct():
.... print 'Ciao'
....Ciao
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,701
Latest member
XavierQ83

Latest Threads

Top