
Python hat das Rekursionslimit, die maximale Tiefe des Python-Interpreter-Stacks. Wenn Sie eine tiefe Rekursion benötigen, müssen Sie das Limit mit Funktionen im sys-Modul der Standardbibliothek höher setzen.
Die Anzahl der Rekursionen ist auch durch die Stapelgröße begrenzt. Sie können die maximale Stapelgröße in einigen Umgebungen mit dem Ressourcenmodul ändern. Es funktionierte unter Ubuntu, aber nicht unter Windows oder Mac in meiner Umgebung.
Dieser Artikel hat folgenden Inhalt.
- Holen Sie sich den aktuellen Wert des Rekursionslimits:
sys.getrecursionlimit()
- Stellen Sie den aktuellen Wert der Rekursionsgrenze ein:
sys.setrecursionlimit()
- Ändern Sie die maximale Größe des Aufrufstapels:
resource.setrlimit()
Der Beispielcode wurde auf Ubuntu ausgeführt.
Holen Sie sich den aktuellen Wert des Rekursionslimits:sys.getrecursionlimit()
Den aktuellen Wert des Rekursionslimits erhalten Sie mit sys.getrecursionlimit().
import sys
import resource
print(sys.getrecursionlimit())
# 1000
Im Beispiel ist es 1000, aber es kann in einigen Umgebungen anders sein. Das hier importierte Ressourcenmodul wird später verwendet. Beachten Sie, dass das Ressourcenmodul unter Windows nicht verfügbar ist.
Definieren Sie sterben folgende einfache rekursive Funktion. If eine positive ganze Zahl n angegeben WIRD, ist die Anzahl der Rekursionen n.
def recu_test(n):
if n == 1:
print('Finish')
return
recu_test(n - 1)
Ein Fehler (RecursionError) WIRD ausgelöst, WENN SIE n größer als das Rekursionslimit angeben.
recu_test(950)
# Finish
# recu_test(1500)
# RecursionError: maximum recursion depth exceeded in comparison
Beachten Sie, dass der Wert von sys.getrecursionlimit() nicht unbedingt die maximale Anzahl von Rekursionen ist, sondern die maximale Tiefe des Python-Interpreter-Stacks, sodass ein Fehler ausgelöst wird, selbst wenn die Anzahl von Rekursionen geringfügig unter diesem Wert liegt.
Das Rekursionslimit ist nicht das Rekursionslimit, sondern die maximale Tiefe des Python-Interpreterstapels.
Python – max. Rekursion ist nicht genau das, was sys.getrecursionlimit() behauptet. Woher? – Paketüberfluss
# recu_test(995)
# RecursionError: maximum recursion depth exceeded while calling a Python object
Stellen Sie den aktuellen Wert der Rekursionsgrenze ein:sys.setrecursionlimit()
Sie können den aktuellen Wert des Rekursionslimits mit sys.setrecursionlimit() festlegen.
Größere Werte ermöglichen eine tiefere Rekursion.
sys.setrecursionlimit(2000)
print(sys.getrecursionlimit())
# 2000
recu_test(1500)
# Finish
Ein Fehler wird ausgelöst, wenn der angegebene Wert zu klein oder zu groß ist.
Das höchstmögliche Limit ist plattformabhängig. Ein Benutzer muss das Limit möglicherweise höher festlegen, wenn er ein Programm hat, das eine tiefe Rekursion erfordert, und eine Plattform, die ein höheres Limit unterstützt. Dies sollte mit Vorsicht erfolgen, da ein zu hohes Limit zu einem Absturz führen kann.
Wenn das neue Limit bei der aktuellen Rekursionstiefe zu niedrig ist, WIRD Eine RecursionError-Ausnahme ausgelöst.
sys.setrecursionlimit() – Systemspezifische Parameter und Funktionen – Dokumentation zu 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
Die Rekursionsgrenze WIRD auch durch die Stapelgröße begrenzt, wie im Folgenden erläutert WIRD.
Ändern Sie die maximale Größe des Aufrufstapels: resource.setrlimit()
Auch wenn mit sys.setrecursionlimit() ein großer Wert gesetzt wird, können Sie nicht viele Rekursionen ausführen. Ein Segmentierungsfehler tritt wie folgt auf.
sys.setrecursionlimit(10 ** 9)
print(sys.getrecursionlimit())
# 1000000000
recu_test(10 ** 4)
# Finish
# recu_test(10 ** 5)
# Segmentation fault
In Python können Sie die maximale Größe des Aufrufstapels mit dem Ressourcenmodul in der Standardbibliothek ändern. Beachten Sie, dass das Ressourcenmodul Unix-spezifisch ist und nicht unter Windows verwendet werden kann.
Sie können das Limit der Ressource als (weiches Limit, hartes Limit) mit resource.getrlimit() erhalten. Geben Sie als Ressource resource.RLIMIT_STACK an, dass die maximale Größe der Aufrufliste des aktuellen Prozesses angezeigt wird.
print(resource.getrlimit(resource.RLIMIT_STACK))
# (8388608, -1)
In diesem Beispiel ist das Soft-Limit 8388608 (8388608 B = 8192 KB = 8 MB) und das Hard-Limit -1 (unbegrenzt).
Sie können das Limit der Ressource mit resource.setrlimit() ändern.
Das Festlegen des weichen Limits auf -1 ermöglicht eine tiefe Rekursion, die zuvor nicht ausgeführt werden konnte.
resource.setrlimit(resource.RLIMIT_STACK, (-1, -1))
print(resource.getrlimit(resource.RLIMIT_STACK))
# (-1, -1)
recu_test(10 ** 5)
# Finish
Hier WIRD das Softlimit zu Experimentierzwecken auf -1 gesetzt, aber in der Praxis wäre es sicherer, es auf einen angesehenen Wert zu begrenzen.
Beachten Sie, dass auf dem Mac der Fehler ValueError: Not Allow to Raise Maximum Limit ausgegeben wird, wenn das Soft-Limit auf -1 gesetzt ist. Das Ausführen des Skripts mit sudo hat nicht funktioniert. Vielleicht ist es durch das System begrenzt.
Ein Prozess mit der effektiven UID des Superusers kann jeden gültigen Grenzwert anfordern, einschließlich unbegrenzt, aber ValueError wird dennoch ausgelöst, wenn der angeforderte Grenzwert den vom System auferlegten Grenzwert überschreitet.
resource.setrlimit() – Informationen zur Ressourcennutzung – Dokumentation zu Python 3.10.4