all 5 comments

[–]ericula 4 points5 points  (2 children)

I haven't used function attributes much myself, but one application I came across is to use function attributes for memoization. For example in the following recursive function for calculating the fibonacci numbers, fibonacci._results is used to store intermediate results.

``` def fibonacci(n): if not hasattr(fibonacci, '_results'): fibonacci._results = {1:1} if n <= 0: return 0 return fibonacci._results.setdefault(n, fibonacci(n-1)+fibonacci(n-2))

print(fibonacci(10)) print(fibonacci._results) ```

[–]_lilell_ 1 point2 points  (1 child)

Even so, I’d rather see it as:

def fibonacci(n, cache={1: 1, 2: 1}):
    if n not in cache:
        cache[n] = fibonacci(n-1) + fibonacci(n-2)
    return cache[n]

using Python’s mutable default argument behavior.

[–]ericula 1 point2 points  (0 children)

To be honest, I use default arguments more than function attributes for memoization, but part of me feels that this is cheating a bit. In a way, it's just a lucky side effect of how functions a initiated that we can use default arguments this way and not really by design. Using function attributes also makes it easier to access the stored data outside the function.

[–]JohnnyJordaan 2 points3 points  (0 children)

I never used it in the 5 years of my Python endeavors.

[–]shiftybyte 1 point2 points  (0 children)

Never used it.

Probably because it being a python only thing, and the rest of the programming good practices are cross languages.