Эпиграф: def short_story(): print ( "У попа была собака, он ее любил." ) print ( "Она съела кусок мяса, он ее убил," ) print ( "В землю закопал и надпись написал:" ) short_story() |
Как мы видели выше, функция может вызывать другую функцию. Но функция также может вызывать и саму себя! Рассмотрим это на примере функции вычисления факториала. Хорошо известно, что , . А как вычислить величину для большого ? Если бы мы могли вычислить величину , то тогда мы легко вычислим , поскольку !. Но как вычислить ? Если бы мы вычислили , то мы сможем вычисли и . А как вычислить ? Если бы... В конце концов, мы дойдем до величины , которая равна . Таким образом, для вычисления факториала мы можем использовать значение факториала для меньшего числа. Это можно сделать и в программе на Питоне:
def factorial(n): if n = = 0 : return 1 else : return n * factorial(n - 1 ) |
Подобный прием (вызов функцией самой себя) называется рекурсией, а сама функция называется рекурсивной.
Рекурсивные функции являются мощным механизмом в программировании. К сожалению, они не всегда эффективны (об этом речь пойдет позже). Также часто использование рекурсии приводит к ошибкам, наиболее распространенная из таких ошибок – бесконечная рекурсия, когда цепочка вызовов функций никогда не завершается и продолжается, пока не кончится свободная память в компьютере. Пример бесконечной рекурсии приведен в эпиграфе к этому разделу. Две наиболее распространенные причины для бесконечной рекурсии:
- Неправильное оформление выхода из рекурсии. Например, если мы в программе вычисления факториала
забудем поставить проверку
if n == 0
, тоfactorial(0)
вызоветfactorial(-1)
, тот вызоветfactorial(-2)
и т.д. - Рекурсивный вызов с неправильными параметрами. Например, если функция
factorial(n)
будет вызыватьfactorial(n)
, то также получиться бесконечная цепочка.
Поэтому при разработке рекурсивной функции необходимо прежде всего оформлять условия завершения рекурсии и думать, почему рекурсия когда-либо завершит работу.