In the body of the function, one sometimes needs to access the function itself (for recursive calls or function attribute access). Using the function name doesn't work if it is bound to another object later.
This recipe introduces a 'bindfunction' decorator addressing this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | def bindfunction(f):
def bound_f(*args, **kwargs):
return f(bound_f, *args, **kwargs)
bound_f.__name__ = f.__name__
return bound_f
# ----- Examples of use ----------
>>> @bindfunction
... def factorial(this_function, n):
... if n > 0:
... return n * this_function(n - 1)
... else:
... return 1
...
>>> factorial(5)
120
>>> fac = factorial
>>> factorial = 'spam'
>>> fac(8) # still works!
40320
>>> @bindfunction
... def counter(counter, total=None):
... if total is not None:
... counter.total = total
... else:
... counter.total += 1
... return counter.total
...
>>> counter(0)
>>> counter()
1
>>> counter()
2
>>> c = counter
>>> counter = 'Ni'
>>> c()
3
>>> c()
4
|
The recipe implements part of the functionality in PEP 3130 without the need of a new builtin. See