UnboundLocalError with extra code after return

John Posner jjposner at optimum.net
Wed Sep 30 20:31:34 CEST 2009


Duncan Booth wrote:

>>/ class CallableOnlyOnce(object):
/    def __init__(self, func):
        self.func = func
    def __call__(self):
        f = self.func
        if f:
            self.func = None
            return f()

>>>/ def callonce(func):
/	return CallableOnlyOnce(func)

>>>/ @callonce
/def t2():
    print "T2 called"

    
>>>/ t2()
/T2 called
>>>/ t2()
/>>>/ /


You don't need both the CallableOnlyOnce class and the callonce function. How about the following ... just for fun, it provides the extra functionality of counting the number of times a function was *called*, even though it was *executed* only once:

--------------------------
class ExecOnlyOnce(object):
    def __init__(self, f):
        print "Making function '%s' into a one-shot" % f.__name__
        self.func = f
        self.func_call_count = 0

    def __call__(self):
        print "Calling one-shot function:", self.func.__name__
        self.func_call_count += 1
        if self.func_call_count == 1:
            return self.func()

@ExecOnlyOnce
def func1():
    print "  inside original function: func1"
    return 111

@ExecOnlyOnce
def func2():
    print "  inside original function: func2"
    return 222

# run the functions
# collect return values just once for each function
r1 = func1()
r2 = func2()
func1()
func1()
func2()
func1()

# summary
print "\nSummary:"
for fn in (func1, func2):
    print "Function '%s' was called %d times" % (fn.func.__name__, fn.func_call_count)

print "r1 =", r1
print "r2 =", r2
--------------------------

Output:

Making function 'func1' into a one-shot
Making function 'func2' into a one-shot
Calling one-shot function: func1
  inside original function: func1
Calling one-shot function: func2
  inside original function: func2
Calling one-shot function: func1
Calling one-shot function: func1
Calling one-shot function: func2
Calling one-shot function: func1

Summary:
Function 'func1' was called 4 times
Function 'func2' was called 2 times
r1 = 111
r2 = 222

-John





More information about the Python-list mailing list