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.