Maximum recursion depth reached faster when using functools.lru_cache

I played with memoization and recursion in python 3.3

Ignoring the fact that python is the wrong language for this, I found that I get inconsistent results between using functools.lru_cache for memoize and not using functools.lru_cache

I do not change the recursion limit - it remains by default, for me it is 1000.

To test the problem, I wrote a simple recursive function to sum the numbers from 1 to i

#!/usr/bin/python

def sumtil(i):
"""Recursive function to sum all numbers from 1 through i"""

    # Base case, the sum of all numbers from 1 through 1 is 1... 
    if i == 1:
        return 1
    else:
        return i+sumtil(i-1)

# This will not throw an exception
sumtil(998)

# This will throw an exception
sumtil(999)

Performing this function in normal mode, I can conveniently use sumtil(998)it without allowing recursion restrictions. sumtil(999)or higher throws an exception.

, @functools.lru_cache(), 3 , sumtil(333)

#!/usr/bin/python

import functools 

@functools.lru_cache(maxsize=128)
def sumtil(i):
    """Recursive function to sum all numbers from 1 through i"""

    # Base case, the sum of all numbers from 1 through 1 is 1... 
    if i == 1:
        return 1
    else:
        return i+sumtil(i-1)

# This will not throw an exception
sumtil(332)

# This will throw an exception
sumtil(333)

332 * 3 = 996, 333 * 3 = 999, , lru_cache , .

functools.lru_cache memoize ?

+5
1

, "" . :

>>> def foo(f):
...   def bar(i):
...     if i == 1:
...       raise Exception()
...     return f(i)
...   return bar
...
>>> @foo
... def sumtil(i):
...     if i == 1:
...         return 1
...     else:
...         return i+sumtil(i-1)
...
>>> sumtil(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in bar
  File "<stdin>", line 6, in sumtil
  File "<stdin>", line 5, in bar
  File "<stdin>", line 6, in sumtil
  File "<stdin>", line 4, in bar
Exception
>>>

, /, ( Python runtime, , ).

def foo(f):
  def bar(*args,**kwargs):
    return f(*args,**kwargs)
  return bar

. :

  • unecorated: 1000
  • : 500
  • : 334
+5

All Articles