Skip to content

Abrufen und Setzen der Rekursionsgrenze in Python (sys.getrecursionlimit, setrecursionlimit)

Python

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