Bạn gọi test(45)
. Điều này kiểm tra xem 45 > 9
có đúng không, do đó, nó gọi test(35)
(45 - 10), mà không trả về kết quả của nó. Điều tương tự cũng xảy ra với test(25)
và test(15)
, cho đến khi cuối cùng test(5)
được gọi.
Bản in này 'giá trị thực 5' và sau đó trả về 5. Nhưng trả lại kết quả từ hàm luôn là trả về cho người gọi trực tiếp của hàm này. Nó không nhảy ngay lập tức thông qua một số cuộc gọi; sau khi tất cả, người gọi có thể muốn làm điều gì đó với kết quả trả về trước khi trả lại một cái gì đó cho số đó là số gọi. Trong trường hợp này, mặc dù chỉ có test(5)
trả về bất kỳ thứ gì; tất cả những người khác gọi số test(x - 10)
, chờ điều đó để trả lại, bỏ qua bất kỳ điều gì nó trả về, và sau đó (ngầm) trả về None
. Kể từ khi yêu cầu ngoài cùng test(45)
là một trong những trường hợp này, những gì bạn nhận được là None
.
Dưới đây là một nỗ lực tại một hình dung về những gì sẽ xảy ra:
test(45):
| test(35):
| | test(25):
| | | test(15):
| | | | test(5):
| | | | | print('real value',5)
| | | | | return 5 to test(15)
| | | | return None to test(25)
| | | return None to test(35)
| | return None to test(45)
| return None
Bạn không gọi test(5)
trong phiên dịch, test(5)
được gọi từ bên trong một lời gọi hàm. Vì vậy, sự trở lại từ test(5)
chuyển đến mà gọi hàm. Thực tế là đây là một chức năng tự gọi là hoàn toàn không liên quan. Bạn sẽ nhận được chính xác kết quả tương tự nếu mã của bạn trông như thế này:
def test45(x):
if x > 9 :
test35(x - 10)
else:
print('real value',x)
return x
def test35(x):
if x > 9 :
test25(x - 10)
else:
print('real value',x)
return x
def test25(x):
if x > 9 :
test15(x - 10)
else:
print('real value',x)
return x
def test15(x):
if x > 9 :
test5(x - 10)
else:
print('real value',x)
return x
def test5(x):
if x > 9 :
print 'No more tests :('
else:
print('real value',x)
return x
Thử nghiệm (x) chức năng bạn gọi với 'x = 45' là giống như gọi test45(45)
. Tôi hy vọng bạn có thể thấy lý do tại sao rõ ràng là None
phải được trả lại khi đệ quy không phải là tham gia. Vâng, khi đệ quy được tham gia, không có gì thay đổi. Câu lệnh return
không biết và cũng không quan tâm liệu nó có trả về từ một hàm được gọi đệ quy hay không, nó hoạt động chính xác theo cùng một cách trong cả hai trường hợp.
Trong thực tế, đệ quy không phải là bất cứ điều gì "đặc biệt"; nó hoạt động giống hệt như các cuộc gọi hàm bình thường. Bạn nhận được thông tin từ thứ gọi bạn qua các đối số và bạn trả lại thông tin về thứ gọi là bạn bằng cách quay lại. Nếu bạn không trả lại thứ gì đó (có lẽ chỉ trong một cánh tay của if
), thì None
sẽ được trả lại cho người gọi của bạn, bất kể bạn gọi bất kỳ chức năng nào khác trong nhánh đó, bất kể chức năng đó có thể trở lại như thế nào nếu bạn gọi một cái gì đó, và bất kể cho dù chức năng bạn gọi xảy ra là chức năng tương tự bạn đang ở bên trong.
Nó chính xác giống như cuộc gọi không đệ quy: nếu bạn muốn truyền giá trị trả về từ hàm bạn gọi, bạn phải tự làm điều đó, với từ khóa 'return'. Gọi một hàm tạo ra giá trị trả về của nó, nhưng nó tùy thuộc vào bạn để làm điều gì đó với giá trị trả về đó, cho dù hàm được gọi là đệ quy hay không. –