
Python a la limite de récursivité, la profondeur maximale de la pile de l’interpréteur Python. Si vous avez besoin d’une récursivité profonde, vous devez définir une limite plus élevée avec des fonctions dans le module sys de la bibliothèque standard.
Le nombre de récursions est également limité par la taille de la pile. Vous pouvez modifier la taille maximale de la pile avec le module de ressources dans certains environnements. Cela a fonctionné sur Ubuntu mais pas sur Windows ou Mac dans mon environnement.
Cet article décrit le contenu suivant.
- Obtenez la valeur actuelle de la limite de récursivité :
sys.getrecursionlimit() - Définissez la valeur actuelle de la limite de récursivité :
sys.setrecursionlimit() - Modifiez la taille maximale de la pile des appels :
resource.setrlimit() 
L’exemple de code suivant a été exécuté sur Ubuntu.
Obtenez la valeur actuelle de la limite de récursivité :sys.getrecursionlimit()
Vous pouvez obtenir la valeur actuelle de la limite de récursivité avec sys.getrecursionlimit().
import sys
import resource
print(sys.getrecursionlimit())
# 1000
Dans l’exemple, c’est 1000, mais cela peut être différent dans certains environnements. Le module de ressources importé ici est utilisé ultérieurement. Notez que le module de ressources n’est pas disponible sous Windows.
Définissez la fonction récursive simple suivante. Si un entier positif n est spécifié, le nombre de récursions est n.
def recu_test(n):
    if n == 1:
        print('Finish')
        return
    recu_test(n - 1)
Une erreur (RecursionError) est déclenchée si vous spécifiez n supérieur à la limite de récursivité.
recu_test(950)
# Finish
# recu_test(1500)
# RecursionError: maximum recursion depth exceeded in comparison
Notez que la valeur de sys.getrecursionlimit() n’est pas strictement le nombre maximal de récursions, mais la profondeur maximale de la pile de l’interpréteur Python, donc une erreur est levée même si le nombre de récursions est légèrement inférieur à cette valeur.
La limite de récursivité n’est pas la limite de récursivité mais la profondeur maximale de la pile de l’interpréteur python.
python – La récursivité maximale n’est pas exactement ce que prétend sys.getrecursionlimit(). Comment venir? – Débordement de pile
# recu_test(995)
# RecursionError: maximum recursion depth exceeded while calling a Python object
Définissez la valeur actuelle de la limite de récursivité :sys.setrecursionlimit()
Vous pouvez définir la valeur actuelle de la limite de récursivité avec sys.setrecursionlimit().
Des valeurs plus grandes permettent une récursivité plus profonde.
sys.setrecursionlimit(2000)
print(sys.getrecursionlimit())
# 2000
recu_test(1500)
# Finish
Une erreur est générée si la valeur spécifiée est trop petite ou trop grande.
La limite la plus élevée possible dépend de la plate-forme. Un utilisateur peut avoir besoin de définir une limite plus élevée lorsqu’il a un programme qui nécessite une récursivité profonde et une plate-forme qui prend en charge une limite plus élevée. Cela doit être fait avec précaution, car une limite trop élevée peut entraîner un plantage.
Si la nouvelle limite est trop basse à la profondeur de récursivité actuelle, une exception RecursionError est déclenchée.
sys.setrecursionlimit() — Paramètres et fonctions spécifiques au système — Documentation Python 3.10.4
sys.setrecursionlimit(4)
print(sys.getrecursionlimit())
# 4
# sys.setrecursionlimit(3)
# RecursionError: cannot set the recursion limit to 3 at the recursion depth 1: the limit is too low
sys.setrecursionlimit(10 ** 9)
print(sys.getrecursionlimit())
# 1000000000
# sys.setrecursionlimit(10 ** 10)
# OverflowError: signed integer is greater than maximum
La limite de récursivité est également limitée par la taille de la pile, comme expliqué ci-après.
Modifier la taille maximale de la pile des appels : resource.setrlimit()
Même si une grande valeur est définie avec sys.setrecursionlimit(), vous ne pouvez pas exécuter un grand nombre de récursions. Un défaut de segmentation se produit comme suit.
sys.setrecursionlimit(10 ** 9)
print(sys.getrecursionlimit())
# 1000000000
recu_test(10 ** 4)
# Finish
# recu_test(10 ** 5)
# Segmentation fault
En Python, vous pouvez modifier la taille maximale de la pile d’appels avec le module de ressources de la bibliothèque standard. Notez que le module de ressources est spécifique à Unix et ne peut pas être utilisé sous Windows.
Vous pouvez obtenir la limite de la ressource sous la forme (limite souple, limite stricte) avec resource.getrlimit(). Spécifiez resource.RLIMIT_STACK, qui représente la taille maximale de la pile d’appels du processus en cours, en tant que ressource.
print(resource.getrlimit(resource.RLIMIT_STACK))
# (8388608, -1)
Dans cet exemple, la limite logicielle est 8388608 (8388608 B = 8192 Ko = 8 Mo) et la limite stricte est -1 (illimité).
Vous pouvez modifier la limite de la ressource avec resource.setrlimit().
La définition de la limite souple à -1 permet une récursivité profonde qui ne pouvait pas être exécutée auparavant.
resource.setrlimit(resource.RLIMIT_STACK, (-1, -1))
print(resource.getrlimit(resource.RLIMIT_STACK))
# (-1, -1)
recu_test(10 ** 5)
# Finish
Ici, la limite souple est définie sur -1 à des fins d’expérimentation, mais en pratique, il serait plus sûr de la limiter à une valeur appropriée.
Notez qu’une erreur, ValueError: not allow to raise maximum limit, est générée sur Mac lorsque la limite logicielle est définie sur -1. L’exécution du script avec sudo n’a pas fonctionné. Peut-être que c’est limité par le système.
Un processus avec l’UID effectif de super-utilisateur peut demander n’importe quelle valeur limite valide, y compris illimitée, mais ValueError sera toujours déclenchée si la limite demandée dépasse la limite imposée par le système.
resource.setrlimit() — Informations sur l’utilisation des ressources — Documentation Python 3.10.4
