W przypadku zmiany kodu do
i = 0
def foo():
global i
i += 1
print i
try :
foo()
except RuntimeError :
# This call recursively goes off toward infinity, apparently.
foo()
finally:
i -= 1
print i
foo()
Będziesz zauważyć, że wyjście oscyluje skrócie poniżej 999 (1000 jest domyślny próg rekurencji Pythona). Oznacza to, że gdy granica jest trafiony (RuntimeError
), że w ubiegłym wezwanie foo()
jest zakończona, a drugi jest wyłączony, aby go natychmiast wymienić.
Jeśli podnieść KeyboardInterrupt
będziesz obserwować, jak cała ślad jest zakończony na raz.
UPDATE
ciekawe drugie wezwanie foo()
nie jest chroniony przez try ... except
-blok więcej. W związku z tym wniosek ostatecznie zostanie rozwiązany. To staje się widoczne, jeśli ustawisz limit rekursji na mniejszą liczbę, np. wyjście dla sys.setrecursionlimit(3)
:
$ python test.py
1
2
1
2
1
0
Traceback (most recent call last):
File "test.py", line 19, in <module>
foo()
File "test.py", line 14, in foo
foo()
File "test.py", line 14, in foo
foo()
RuntimeError
Cóż, po prostu zachować na wywołanie 'foo', bez warunku zatrzymania, więc nadal będzie rekursja wiecznie. Nawet jeśli otrzymasz wyjątek, powtarzasz _again_. –
Czy w Pythonie nie powinno zabraknąć pamięci? Czy też stos wywołający jest wyczyszczony po wystąpieniu "RuntimeError"? – rectangletangle
Ewentualnie pyton optymalizuje go do iteracji – Blorgbeard