BOMBOLOM.COM

(python) Maximum Recursion Depth Exceeded

Este é um post de José Lopes.

Se obter a seguinte mensagem de erro quando executar uma função de Python:

RuntimeError: maximum recursion depth exceeded

Significa que o limite de repetição foi ultrapassado (recursion limit em inglês), podendo o problema ser resolvido de uma forma relativamente fácil.

O limite de repetição existe para evitar a repetição infinita que causaria um overflow e consequentemente o crash do Python.

Para verificar o actual limite pode-se fazer:

import sys
print sys.getrecursionlimit()

Isto vai imprimir para o ecrã um número que representa o actual limite de repetição.
Este número pode ser alterado fazendo:

sys.setrecursionlimit(n)

Onde n deverá ser um número inteiro que define o novo limite.

Ao ter dito que o problema podia ser resolvido de uma forma relativamente fácil foi intencional.
Normalmente definindo um novo limite de repetição resolve-se o problema mas, como este limite depende dos recursos da plataforma que se está a utilizar, pode não ser suficiente e obrigar a uma revisão ou optimização do código.

O limite de repetição pode ser sempre alterado no caso do programa necessitar de uma repetição de grau elevado e se a plataforma suportar um valor mais elevado.

Pergunta-se agora qual o valor máximo suportado pela minha plataforma?

Como este valor não vem escrito em lado nenhum teremos de criar uma bateria de testes para o determinar. Fazendo uma busca pela internet encontramos um programa que testa as capacidades do sistema, estando em svn.python.org.

No entanto, na minha opinião, a sua utilização é um pouco excessiva porque nem sempre necessitamos de saber os limites máximos mas sim o limite necessário para a nossa aplicação, o que requere uma abordagem mais simplificada.

Imaginando que temos a função dos números de Fibonacci que foi definida no post relativo a Criar Memorizador que terá como valor máximo de utilização por exemplo 1000.
Vamos testá-la para o seu máximo (ou outro valor superior para margem de segurança):

fibonacci = memo(fibonacci)
fibonacci(1000)

Provavelmente vamos obter o erro de RuntimeError: maximum recursion depth exceeded.
Para determinar o valor do limite de repetição apropriado para este caso podemos fazer:

fibonacci = memo(fibonacci)
n = 2000
while 1:
  sys.setrecursionlimit(n)
  try: 
    fibonacci(1000)
  except RuntimeError:
    pass
  else:
    break
  n += 500
  print n

Obterá um resultado do tipo:

2500
3000
3500

O valor de 3500 será suficiente para a função até ao valor testado de 1000.

É verdade que nós temos sempre uma ideia da variação de dados para as nossas aplicações, o que afecta o nosso design e código da solução, pelo que não acho tão desprezável obter os limites para um caso particular em vez de saber os limites máximos do sistema.
Isto depende sempre da situação em que estamos daí ter mencionado as duas hipóteses.

13.09.2007 | Ler mais | Comentários | Tags ,

Voltar à Página principal | Made with PyBlosxom Site Meter