У меня есть 2 решения проблемы рекурсии, которые мне нужны для функции (на самом деле метода). Я хочу, чтобы он был рекурсивным, но я хочу установить предел рекурсии до 10 и сбросить его после вызова функции (или вообще не связываться с ограничением рекурсии). Может ли кто-нибудь придумать лучший способ сделать это или порекомендовать использовать один вместо других? Я склоняюсь к диспетчеру контекста, потому что он сохраняет мой код более чистым и не устанавливает предела трассировки, но могут быть оговорки?
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()
Я действительно наблюдаю странное поведение с диспетчером контекста. Если я введу main
with recursion_limit(12):
func2()
, он напечатает от 1 до 10. Если я сделаю то же самое из интерпретатора, он напечатает от 1 до 11. Я предполагаю, что что-то происходит под капотом, когда я импортирую вещи?
РЕДАКТИРОВАТЬ: Для потомков это то, что я придумал для функции, которая знает глубину своего вызова. Сомневаюсь, что я бы использовал его в каком-либо производственном коде, но он выполняет свою работу.
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()