UnboundLocalError with extra code after return
Rich Healey
healey.rich at gmail.com
Wed Sep 30 00:37:16 EDT 2009
On Sep 30, 2:15 pm, Rich Healey <healey.r... at gmail.com> wrote:
> I'm trying to write a decorator that causes a function to do nothing
> if called more than once- the reason for this is trivial and to see if
> I can (Read- I'm enjoying the challenge, please don't ruin it for me
> =] )
>
> However I'm getting strange results with Python 2.6.2 on win32.
>
> With this code:
>
> def callonce(func):
> def nullmethod(): pass
> def __():
> return func()
> return __
> @callonce
> def t2():
> print "T2 called"
> t2()
>
> It does exactly what you'd expect, prints "T2 called"
>
> However:
>
> def callonce(func):
> def nullmethod(): pass
> def __():
> return func()
> func = nullmethod
> return ret
> return __
>
> @callonce
> def t2():
> print "T2 called"
> t2()
>
> Gives me:
>
> C:\tmp\callonce>callonce.py
> Traceback (most recent call last):
> File "C:\tmp\callonce\callonce.py", line 27, in <module>
> t2()
> File "C:\tmp\callonce\callonce.py", line 12, in __
> return func()
> UnboundLocalError: local variable 'func' referenced before assignment
>
> Any ideas on why? This looks like a bug to me, but I'm quite new to
> this style of programming so it may be some nuance I'm not aware of.
>
> Thanks in advance.
>
> Rich Healey
In case anyone was paying attention I've now gotten this working- and
raised a whole bunch more questions!
def callonce(func):
func.__RECALL = True
def __():
if func.__RECALL:
func.__RECALL = False
return func()
else:
return
return __
@callonce
def t2():
print "T2 called"
t2()
t2()
t2()
Works as expected- the last two t2() calls do nothing.
It seems that my problem was that I can't assign a new function to the
name func within the callonce() function. I can however interact with
the func object (in this case storing information about whether or not
I'd called it in it's __RECALL item.
Is there a cleaner solution?
I'd originally wanted to define a function that does nothing, and then
point the function to that for subsequent calls (this seems cleaner
overall, if a little longwidned to write)
ie:
def onlyCalledOnce():
global onlyCalledOnce
def nullfunc(): pass
onlyCalledOnce = nullfunc
# Do stuff here
return "Something"
I'll keep plugging at this for a little while I think- thoughts
suggestions welcome!
More information about the Python-list
mailing list