Nếu bạn thay đổi mã để
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ạn sẽ nhận thấy rằng sản lượng dao động ngắn dưới 999 (1000 là giới hạn đệ quy mặc định của Python). Điều đó có nghĩa, khi giới hạn được nhấn (RuntimeError
), cuộc gọi cuối cùng của số foo()
bị chấm dứt và một cuộc gọi khác được đặt để thay thế ngay lập tức.
Nếu bạn tăng KeyboardInterrupt
, bạn sẽ quan sát cách toàn bộ dấu vết đang bị chấm dứt cùng một lúc.
CẬP NHẬT
Điều thú vị là cuộc gọi thứ hai của foo()
không được bảo vệ bởi các try ... except
-block nữa. Vì vậy, ứng dụng sẽ thực sự chấm dứt cuối cùng. Điều này trở thành apparant nếu bạn đặt giới hạn đệ quy thành một số nhỏ hơn, ví dụ: đầu ra cho 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
Vâng, bạn cứ tiếp tục gọi 'foo', không dừng điều kiện, vì vậy nó sẽ tiếp tục gọi lại mãi mãi. Và ngay cả khi bạn nhận được một ngoại lệ, bạn recurse _again_. –
Không nên Python hết bộ nhớ hay gì đó? Hoặc là ngăn xếp cuộc gọi được xóa sau 'RuntimeError'? – rectangletangle
Có thể python đang tối ưu hóa nó thành phép lặp – Blorgbeard