Steven D'Aprano <st...@remove-this-cybersource.com.au> writes: > On Wed, 10 Feb 2010 10:08:47 -0500, John Posner wrote: > >>> This won't work correctly, because old_f still tries to refer to itself >>> under the name "f", and things break very quickly. >> >> They didn't break immediately for me -- what am I missing?: > > The original function f doesn't try to refer to itself in any way. With > no recursive call or access, it doesn't matter what f is named. > > See this example instead: > > >>>> def f(x): > ... if x < 0: > ... print "original" > ... return f(-x) > ... else: > ... return x+1 > ... >>>> f(2) > 3 >>>> f(-2) > original > 3 >>>> >>>> old_f = f >>>> def f(x): > ... if x > 0: > ... return old_f(-x) > ... else: > ... return x > ... >>>> f(-1) > -1 >>>> f(1) > original > original > original > original > original > original > [...] > File "<stdin>", line 3, in f > File "<stdin>", line 4, in f > File "<stdin>", line 3, in f > RuntimeError: maximum recursion depth exceeded
It's not ideal, but you can use a decorator like this to solve this problem: def bindfunction(f): def bound_f(*args, **kwargs): return f(bound_f, *args, **kwargs) bound_f.__name__ = f.__name__ return bound_f >>> @bindfunction ... def factorial(this_function, n): ... if n > 0: ... return n * this_function(n - 1) ... else: ... return 1 ... >>> factorial(15) 1307674368000L >>> fac = factorial >>> fac(15) 1307674368000L >>> factorial = 'foobar' >>> fac(15) 1307674368000L -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list