Моя проблема связана с определенным стилем кода, который очень напоминает рекурсию, но не совсем .Рекурсия - это, по выражению Wikipedia , «метод определения функций, в котором определяемая функция применяется в своем собственном определении».Аналогичным образом взаимная рекурсия применяет другую функцию, которая прямо или косвенно применяет определяемую нами функцию.
Проблема в том, что код, над которым я размышляю и работаю, не использует ту же функцию!Он использует тот же код в другой функции (как метод или замыкание).
Проблема в том, что, хотя мой код одинаков, функции не совпадают.Взгляните на следующий базовый пример взаимной рекурсии:
def is_even(x):
if x == 0:
return True
else:
return is_odd(x - 1)
def is_odd(x):
if x == 0:
return False
else:
return is_even(x - 1)
Это несколько интуитивно понятно и очень четко взаимно рекурсивно.Однако, если я закрою каждую функцию как внутреннюю функцию, которая создается один раз при каждом вызове, она становится менее ясной:
def make_is_even():
def is_even(x):
if x == 0:
return True
else:
return make_is_odd()(x - 1)
return is_even
def make_is_odd():
def is_odd(x):
if x == 0:
return False
else:
return make_is_even()(x - 1)
return is_odd
def is_even2(x):
return make_is_even()(x)
def is_odd2(x):
return make_is_odd()(x)
Без учета оптимизаций, таких как неявное запоминание и т. Д., Это создает цепочку вызовов функций, которая нене является строго рекурсивным, создавая и вызывая различные новые функции, никогда не вызывая одну и ту же функцию дважды.Тем не менее, все эти функции следуют общему шаблону и являются одной и той же функцией, создаваемой снова и снова (возможно, с различными свободными переменными.
И снова, мы можем придумать прямой эквивалент (в конце концов, классына самом деле это просто замыкания, верно;) реализация с использованием классов. Это особенно важно, поскольку этот стиль [вставьте здесь имя] используется, например, в Composite Pattern . Разница в том,что с помощью шаблона проектирования Composite и большинства применений (даже замыканий) экземпляры обычно создаются не на лету, а по сути все так же.
class EvenChecker(object):
def check(self, x):
if x == 0:
return True
else:
return OddChecker().check(x - 1)
class OddChecker(object):
def check(self, x):
if x == 0:
return False
else:
return EvenChecker().check(x - 1)
def is_even3(x):
return EvenChecker().check(x)
def is_odd3(x):
return OddChecker().check(x)
На этот раз цепочка объектоввызовы создания и метода, но принцип тот же. (Я бы на самом деле заметил, что он немного другой, в том смысле, что Python определяет простую обертку для каждого объекта, которая сама каждый раз вызывает одну и ту же функцию - ноэто не обязательно то, что мы должны знать, и это не должно быть правдой для другихее реализации классов и объектов.Но, строго говоря, это является взаимно рекурсивным, а также ... чем-то большим, и это еще одна вещь, которую я хочу знать.)