Skip to content

Ottenere e impostare il limite di ricorsione in Python (sys.getrecursionlimit, setrecursionlimit)

Python

Python ha il limite di ricorsione, la profondità massima dello stack dell’interprete Python. Se si richiede una ricorsione profonda, è necessario impostare il limite più alto con le funzioni nel modulo sys della libreria standard.

Il numero di ricorsioni è limitato anche dalla dimensione dello stack. È possibile modificare la dimensione massima dello stack con il modulo delle risorse in alcuni ambienti. Ha funzionato su Ubuntu ma non su Windows o Mac nel mio ambiente.

In questo articolo vengono descritti i seguenti contenuti.

  • Ottieni il valore corrente del limite di ricorsione:sys.getrecursionlimit()
  • Impostare il valore corrente del limite di ricorsione:sys.setrecursionlimit()
  • Modifica la dimensione massima dello stack di chiamate:resource.setrlimit()

Il seguente codice di esempio è stato eseguito su Ubuntu.

Ottieni il valore corrente del limite di ricorsione:sys.getrecursionlimit()

È possibile ottenere il valore corrente del limite di ricorsione con sys.getrecursionlimit().

import sys
import resource

print(sys.getrecursionlimit())
# 1000

Nell’esempio è 1000, ma potrebbe essere diverso in alcuni ambienti. Il modulo utilizzato importato qui viene in seguito. Si noti che il modulo delle risorse non è disponibile su Windows.

Definire la seguente semplice funzione ricorsiva. Se viene specificato un numero intero positivo n, il numero di ricorsioni è n.

def recu_test(n):
    if n == 1:
        print('Finish')
        return
    recu_test(n - 1)

Viene generato un errore (RecursionError) se si specifica n maggiore del limite di ricorsione.

recu_test(950)
# Finish

# recu_test(1500)
# RecursionError: maximum recursion depth exceeded in comparison

Nota che il valore di sys.getrecursionlimit() non è rigorosamente il numero massimo di ricorsioni, ma la profondità massima dello stack dell’interprete Python, quindi viene generato un errore anche se il numero di ricorsioni è leggermente inferiore a questo valore.

Il limite di ricorsione non è il limite alla ricorsione ma la profondità massima dello stack dell’interprete Python.
python – La ricorsione massima non è esattamente ciò che afferma sys.getrecursionlimit(). Vieni mai? – Troppo pieno dello stack

# recu_test(995)
# RecursionError: maximum recursion depth exceeded while calling a Python object

Impostare il valore corrente del limite di ricorsione:sys.setrecursionlimit()

È possibile impostare il valore corrente del limite di ricorsione con sys.setrecursionlimit().

Valori maggiori consentono una ricorsione più profonda.

sys.setrecursionlimit(2000)

print(sys.getrecursionlimit())
# 2000

recu_test(1500)
# Finish

Viene generato un errore se il valore specificato è troppo piccolo o troppo grande.

Il limite più alto possibile dipende dalla piattaforma. Un utente potrebbe dover impostare il limite più alto quando ha un programma che richiede una ricorsione profonda e una piattaforma che supporta un limite più alto. Questo dovrebbe essere fatto con attenzione, perché un limite troppo alto può portare a un crash.
Se il nuovo limite è troppo basso alla profondità di ricorsione corrente, viene sollevata un’eccezione RecursionError.
sys.setrecursionlimit() — Parametri e funzioni specifici del sistema — Documentazione 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

Il limite di ricorsione è anche limitato dalla dimensione dello stack, come spiegato di seguito.

Modifica la dimensione massima dello stack di chiamate: Resource.setrlimit()

Anche se viene impostato un valore elevato con sys.setrecursionlimit(), non è possibile eseguire un numero elevato di ricorsioni. Un errore di segmentazione si verifica come segue.

sys.setrecursionlimit(10 ** 9)
print(sys.getrecursionlimit())
# 1000000000
recu_test(10 ** 4)
# Finish

# recu_test(10 ** 5)
# Segmentation fault

In Python, puoi modificare la dimensione massima dello stack di chiamate con il modulo delle risorse libreria standard. Si noti che il modulo delle risorse è specifico di Unix e non può essere utilizzato su Windows.

Puoi ottenere il limite della risorsa come (limite morbido, limite rigido) con resource.getrlimit(). Specificare risorsa.RLIMIT_STACK, che rappresenta la dimensione massima dello stack chiamate del processo corrente, come risorsa.

print(resource.getrlimit(resource.RLIMIT_STACK))
# (8388608, -1)

In questo esempio, il limite software è 8388608 (8388608 B = 8192 KB = 8 MB) e il limite rigido è -1 (illimitato).

Puoi modificare il limite della risorsa con Resource.setrlimit().

L’impostazione del limite morbido su -1 consente una ricorsione profonda che non poteva essere eseguita prima.

resource.setrlimit(resource.RLIMIT_STACK, (-1, -1))

print(resource.getrlimit(resource.RLIMIT_STACK))
# (-1, -1)

recu_test(10 ** 5)
# Finish

Qui il limite morbido è impostato su -1 per motivi di sperimentazione, ma in pratica sarebbe più sicuro limitarlo a un valore appropriato.

Si noti che un errore, ValueError: non è consentito aumentare il limite massimo, viene sollevato su Mac quando il limite software è impostato su -1. L’esecuzione dello script con sudo non ha funzionato. Forse è limitato dal sistema.

Un processo con l’UID effettivo del superutente può richiedere qualsiasi valore limite valido, incluso Unlimited, ma ValueError comunque sollevato se il limite richiesto supera il limite imposto dal sistema.
Resource.setrlimit() — Informazioni sull’utilizzo delle risorse — Documentazione Python 3.10.4