Превышена максимальная глубина рекурсии в классе
Я пишу матричный класс и хочу поместить метод того же класса в класс атрибутов
class Matrix:
def __init__(
self,
rows: int=None,
columns: int=None,
values: list[int | float | list[int | float]]=None
) -> None:
self.__rows = 3 if not rows else (3 if rows <= 0 else rows)
self.__columns = 3 if not columns else (3 if columns <= 0 else columns)
self.__values = [
[
random.randint(-10, 10)
for _ in range(self.__columns)
]
for _ in range(self.__rows)
] if not values and self.__rows != 1 \
else [
random.randint(-10, 10)
for _ in range(self.get_columns)
] if self.__rows == 1 else values
self.T = self.__transposition()
def __transposition(self) -> typing.Self:
return Matrix(
self.__columns,
self.__rows,
[
[
self.__values[j][i]
for j in range(self.__rows)
]
for i in range(self.__columns)
]
)
if name == 'main':
a = Matrix(rows=2)
print(a.T)
Но есть глубина рекурсии
File "Matrix.py", line 25, in __init__
self.T = self.__transposition()
^^^^^^^^^^^^^^^^^^^^^^
File "Matrix.py", line 47, in __transposition
return Matrix(
^^^^^^^
RecursionError: maximum recursion depth exceeded
Что можно сделать? Я пытался пропустить его через декоратора статического метода, но ничего не помогло.
Ответы (1 шт):
Ну вы же в __init__
сразу вызываете транспонирование, а в транспонировании создаете новый объект, вот и получается бесконечная рекурсия.
Нужно не вызывать транспонирование при инициализации, а делать его при обращении к атрибуту T
, для этого он должен быть методом с декоратором @property
:
class Matrix:
def __init__(
self,
rows: int=None,
columns: int=None,
values: list[int | float | list[int | float]]=None
) -> None:
...
# Эту строку убираете:
# self.T = self.__transposition()
def __transposition(self) -> typing.Self:
...
@property
def T(self):
return self.__transposition()
if name == 'main':
a = Matrix(rows=2)
print(a.T)
Вместо объявления T
как метода можно записать так:
class Matrix:
def __init__(
self,
rows: int=None,
columns: int=None,
values: list[int | float | list[int | float]]=None
) -> None:
...
# Эту строку убираете:
# self.T = self.__transposition()
def __transposition(self) -> typing.Self:
...
T = property(__transposition)
Суть будет примерно та же, что и выше, но без промежуточного метода, "просто" атрибут T
становится свойством для метода __transposition
.