再帰関数がどのように機能するかを理解していないことは非常に一般的ですが、再帰関数は通常の関数とまったく同じように機能するため、関数と戻り値がどのように機能するかを理解していないことを示しています。
print 4
これは、print
ステートメントが値を出力する方法を知っているために機能します。値が与えられ、それ4
を印刷します。
print 3 + 1
ステートメントは、print
印刷方法を理解していません3 + 1
。3 + 1
値ではなく、式です。幸いなことprint
に、式が表示されないため、式を印刷する方法を知る必要はありません。Pythonは、式ではなく、物に値を渡します。つまり、Pythonが行うことは、コードが実行されるときに式を評価することです。この場合、その結果、価値4
が生み出されます。次に、値4
がステートメントに与えられ、print
ステートメントが喜んで出力します。
def f(x):
return x + 1
print f(3)
これは上記と非常によく似ています。f(3)
は式であり、値ではありません。print
それでは何もできません。Pythonは式を評価して、印刷に与える値を生成する必要があります。これは、名前を調べて、幸いにもステートメントf
によって作成された関数オブジェクトを見つけ、引数を使用して関数を呼び出すことによって行われます。def
3
これにより、関数の本体がにx
バインドされて実行され3
ます。の場合と同様にprint
、return
ステートメントは式に対して何も実行できないx + 1
ため、Pythonはその式を評価して値を見つけようとします。x + 1
with x
bound to3
は値を生成し4
、それが返されます。
関数から値を返すと、関数呼び出し式の評価がその値になります。したがって、に戻ってprint f(3)
、Pythonは式f(3)
を値に正常に評価しました4
。その後、印刷print
できます。
def f(x):
return x + 2
def g(y):
return f(y * 2)
print g(1)
ここでも、g(2)
は値ではなく式であるため、評価する必要があります。評価g(2)
するf(y * 2)
と、にy
バインドされ1
ます。y * 2
値ではないので、それを呼び出すことはできませんf
。最初にそれを評価する必要があります。これにより、値が生成されます2
。次に、を呼び出すことができます。これは、にバインドされf
て2
戻ります。から返され、内部の式の値になる値に評価されます。これは最終的に返す値を与えるので、式は値に評価され、次に出力されます。x + 2
x
2
x + 2
4
f
f(y * 2)
g
g
g(1)
4
Pythonを評価するためにドリルダウンすると、f(2)
Pythonはすでに評価の途中でありg(1)
、何が評価されるかがわかると、適切な場所に戻ることに注意してくださいf(2)
。
それでおしまい。これですべてです。再帰関数について特別なことを理解する必要はありません。return
関数のこの特定の呼び出しを呼び出した式を、に与えられた値にしreturn
ます。関数を呼び出す関数を呼び出す関数を呼び出す高レベルの式ではなく、即時式。最も内側のもの。中間の関数呼び出しがたまたまこれと同じ関数であるかどうかは関係ありません。この関数が再帰的に呼び出されたかどうかを知る方法はありませんreturn
。ましてや、2つの場合で動作が異なることは言うまでもありません。return
常に常に常にその値を直接に返しますそれが何であれ、この関数の呼び出し元。これらのステップのいずれかを「スキップ」して、値をさらに外側の呼び出し元(再帰関数の最も外側の呼び出し元など)に返すことは決してありません。
しかし、これが機能することを確認fib(3)
するために、の評価をより詳細に追跡してみましょう。
fib(3):
3 is not equal to 0 or equal to 1
need to evaluate fib(3 - 1) + fib(3 - 2)
3 - 1 is 2
fib(2):
2 is not equal to 0 or equal to 1
need to evaluate fib(2 - 1) + fib(2 - 2)
2 - 1 is 1
fib(1):
1 is equal to 0 or equal to 1
return 1
fib(1) is 1
2 - 2 is 0
fib(0):
0 is equal to 0 or equal to 1
return 1
fib(0) is 1
so fib(2 - 1) + fib(2 - 2) is 1 + 1
fib(2) is 2
3 - 2 is 1
fib(1):
1 is equal to 0 or equal to 1
return 1
fib(1) is 1
so fib(3 - 1) + fib(3 - 2) is 2 + 1
fib(3) is 3
より簡潔に、をfib(3)
返しますfib(2) + fib(1)
。fib(1)
1をfib(3)
返しますが、それに加えて。の結果を返しますfib(2)
。fib(2)
戻りますfib(1) + fib(0)
; これらは両方とも戻り1
ます。したがって、それらを合計するとfib(2)
、の結果が得られ2
ます。に戻ってfib(3)
、それはでしたfib(2) + fib(1)
、私たちは今それがであると言う立場に2 + 1
あり3
ます。
あなたが見逃していた重要な点は、fib(0)
またはfib(1)
が戻る間1
、それら1
はより高いレベルの呼び出しが合計している式の一部を形成するということでした。