Tengo 2 soluciones para un problema de recursión que necesito para una función (en realidad un método). Quiero que sea recursivo, pero quiero establecer el límite de recursión en 10 y restablecerlo después de que se llame a la función (o no interferir con el límite de recursividad). ¿Alguien puede pensar en una mejor manera de hacer esto o recomendar usar uno sobre los demás? Me estoy inclinando hacia el administrador de contexto porque mantiene mi código más limpio y no establece el límite de seguimiento, pero puede haber advertencias?establecer el límite de recursión de python para una función
import sys
def func(i=1):
print i
if i > 10:
import sys
sys.tracebacklimit = 1
raise ValueError("Recursion Limit")
i += 1
func(i)
class recursion_limit(object):
def __init__(self, val):
self.val = val
self.old_val = sys.getrecursionlimit()
def __enter__(self):
sys.setrecursionlimit(self.val)
def __exit__(self, *args):
sys.setrecursionlimit(self.old_val)
raise ValueError("Recursion Limit")
def func2(i=1):
"""
Call as
with recursion_limit(12):
func2()
"""
print i
i += 1
func2(i)
if __name__ == "__main__":
# print 'Running func1'
# func()
with recursion_limit(12):
func2()
Aunque veo un comportamiento extraño con el administrador de contexto. Si pongo en el principal
with recursion_limit(12):
func2()
Imprime 1 a 10. Si hago lo mismo desde el intérprete imprime 1 a 11. Asumo que hay algo que hacer bajo el capó cuando la importación cosas?
EDITAR: Para la posteridad esto es lo que he encontrado para una función que conoce su profundidad de llamada. Dudo que lo use en ningún código de producción, pero hace el trabajo bien.
import sys
import inspect
class KeepTrack(object):
def __init__(self):
self.calldepth = sys.maxint
def func(self):
zero = len(inspect.stack())
if zero < self.calldepth:
self.calldepth = zero
i = len(inspect.stack())
print i - self.calldepth
if i - self.calldepth < 9:
self.func()
keeping_track = KeepTrack()
keeping_track.func()
¿Por qué no utilizar 'for _ in xrange (N)' para hacer algo N veces? Es conceptualmente más simple que abusar de un 'RuntimeError', permite llamar a otras funciones sin salir prematuramente (o, lo que es peor, requiere que la persona que llama se encargue de eso), y debería ser más eficiente como una bonificación. – delnan
Cuando lo haces en main, ya estás en una función. Cuando estás en el intérprete, no lo eres. – agf
¿Por qué querrías hacer esto? –