Использование рекурсии с методами класса

Создал класс и столкнулся с такой проблемой, что при вычислении факториала через обычный цикл вычислить можно, а вот с рекурсией нельзя.

Почему так и чем это вызвано?

class Math:
    def __init__(self,n):
        self.n = n
    def factorialRecursion(self,n):
        if self.n == 1:
            return self.n
        else:
            return self.n * factorialRecursion(self.n - 1)
    def factorialSimple(self,n):
        i = 1
        result = 1
        for i in range(1,self.n + 1):
            result *= i
        return result

n = 5
math = Math(n)
print(math.factorialRecursion(n)) # ошибка : функция не определена
print(math.factorialSimple(n)) # выводит 120 

Ответы (2 шт):

Автор решения: MaxU

Попробуйте так:

class Math:
    def factorialRecursion(self, n):
        if n == 1:
            return 1
        else:
            return n * self.factorialRecursion(n - 1)

    def factorialSimple(self, n):
        i = 1
        result = 1
        for i in range(1, n + 1):
            result *= i
        return result


math = Math()
n = 5
print(math.factorialRecursion(n))
print(math.factorialSimple(n))
→ Ссылка
Автор решения: insolor

Можно реализовать так:

class Factorial:
    def __init__(self, n=1):
        self.n = n

    def recursive(self, n=None):
        if n is None:
            n = self.n            

        if n == 1:
            return n
        else:
            return n * self.recursive(n - 1)

    def iterative(self, n=None):
        if n is None:
            n = self.n

        i = 1
        result = 1

        for i in range(1, n + 1):
            result *= i

        return result

print(Factorial(10).recursive())
print(Factorial(10).iterative())
print(Factorial().recursive(10))
print(Factorial().iterative(10))

Т.е. использовать параметр n, переданный в методы, только если он задан, а если не задан, то брать поле объекта.

Но для математических функций как правило не нужно хранить состояние объекта, а нужен только переданный параметр, поэтому можно сделать оба метода статическими (независимыми от self или класса):

class Factorial:
    @staticmethod
    def recursive(n):
        if n == 1:
            return n
        else:
            return n * Factorial.recursive(n - 1)

    @staticmethod
    def iterative(n):
        i = 1
        result = 1

        for i in range(1, n + 1):
            result *= i

        return result


# Работает и без создания объекта
print(Factorial.recursive(10))
print(Factorial.iterative(10))

# Также работает и от объекта класса:
print(Factorial().recursive(10))
print(Factorial().iterative(10))

Это искусственный пример, но если на практике у вас встретится класс, содержащий только статические методы, то стоит подумать о том, чтобы переделать такой класс просто в модуль с функциями.

→ Ссылка