Function attributes
Arnaud Delobelle
arnodel at googlemail.com
Wed Feb 10 13:31:23 EST 2010
Steven D'Aprano <steve at 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
More information about the Python-list
mailing list