Как напечатать класс, который может содержать сам себя - PullRequest
3 голосов
/ 29 апреля 2020

У меня есть класс, который работает аналогично списку. Это может содержать себя, и это приводит к проблемам печати. Python обрабатывает это с заменой рекурсивной части на многоточие. Я могу сделать это, когда вложение просто, где a = []; a.append(a), сравнивая отдельные элементы с самим собой, но когда есть более сложные отношения, это не работает. Какой хороший способ заменить рекурсивные детали с помощью механизма печати Ellipsis или Hijack Pythons? Я попытался создать список из значений из себя и вернуть str(mylist), но я тоже получил ошибку рекурсии.

class foo:
    def __init__(self):
        #stuff happens

    def __repr__(self):
        s = []
        for i in range(self.length):
            if self[i] is self:
                s.append("[...]")
            else:
                s.append(repr(self[i]))
        return f"[{','.join(s)}]"

class bar:
    def __init__(self):
        # stuff happens

    def __repr__(self):
        return str(list(self))

a = foo()
b = foo()
a.append(b)
b.append(a)
print(a)
RecursionError: maximum recursion depth exceeded

a = bar()
b = bar()
a.append(b)
b.append(a)
print(a)
RecursionError: maximum recursion depth exceeded

1 Ответ

2 голосов
/ 30 апреля 2020

Используя reprlib, рекомендованный snakecharmerb, я решил проблему с декоратором reprlib.recursive_repr. Описание этой функции:

@reprlib.recursive_repr(fillvalue="...")

Декоратор для __repr__() методов для обнаружения рекурсивных вызовов в одном потоке. Если выполняется рекурсивный вызов, возвращается fillvalue , в противном случае выполняется обычный вызов __repr__().

Я использую значение заполнения "[...]" со скобками, потому что в противном случае результат может выглядеть как [3, ...], что не красиво и не так, как python форматирует списки.

@reprlib.recursive_repr("[...]")
def __repr__(self):
    return f"[{','.join(map(repr, self))}]"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...