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