reprlib — Альтернативная реализация repr()


Модуль reprlib предоставляет средства для создания представлений объектов с ограничениями на размер результирующих строк. Используется в отладчике Python и может быть полезно и в других контекстах.

Данный модуль предоставляет класс, экземпляр и функцию:

class reprlib.Repr

Класс, предоставляющий службы форматирования, полезные для реализации функций, аналогичных встроенной repr(); добавлены ограничения размера для различных типов объектов, чтобы избежать создания слишком длинных представлений.

reprlib.aRepr

Экземпляр Repr, который используется для обеспечения функции repr(), описанной ниже. Изменение атрибутов этого объекта повлияет на ограничения размера, используемые repr() и отладчиком Python.

reprlib.repr(obj)

Метод repr() aRepr. Возвращает строку, похожую на ту, что возвращает встроенная функция с тем же именем, но с ограничениями на большинство размеров.

В дополнение к инструментам ограничения размера модуль также предоставляет декоратор для обнаружения рекурсивных вызовов __repr__() и замены строки-заполнителя.

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

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

>>> from reprlib import recursive_repr
>>> class MyList(list):
...     @recursive_repr()
...     def __repr__(self):
...         return '<' + '|'.join(map(repr, self)) + '>'
...
>>> m = MyList('abc')
>>> m.append(m)
>>> m.append('x')
>>> print(m)
<'a'|'b'|'c'|...|'x'>

Добавлено в версии 3.2.

Объекты repr

Экземпляры Repr предоставляют несколько атрибутов, используемые для ограничения размера представлений различных типов объектов и методов, форматирующие определённые типы объектов.

Repr.maxlevel

Ограничение глубины создания рекурсивных представлений. По умолчанию 6.

Repr.maxdict
Repr.maxlist
Repr.maxtuple
Repr.maxset
Repr.maxfrozenset
Repr.maxdeque
Repr.maxarray

Ограничения на количество записей, представленных для именованного типа объекта. По умолчанию 4 для maxdict, 5 для maxarray и 6 для остальных.

Repr.maxlong

Максимальное количество символов в представлении целого числа. Цифры выпадают из середины. По умолчанию 40.

Repr.maxstring

Ограничение на количество символов в представлении строки. Обратите внимание, что в качестве источника символов используется «нормальное» представление строки: если в представлении необходимы escape- последовательности, они могут быть искажены при сокращении представления. По умолчанию 30.

Repr.maxother

Ограничение используется для управления размером типов объектов, для которых нет специального метода форматирования в объекте Repr. Он применяется аналогично maxstring. По умолчанию 20.

Repr.repr(obj)

Эквивалент встроенного repr(), в котором используется форматирование, заданное экземпляром.

Repr.repr1(obj, level)

Рекурсивная реализация, используемая repr(). Это использует тип obj, чтобы определить, какой метод форматирования вызывать, передавая ему obj и level. Методы, специфичные для типа, должны вызывать repr1() для выполнения рекурсивного форматирования с level - 1 для значения level в рекурсивном вызове.

Repr.repr_TYPE(obj, level)

Методы форматирования для определенных типов реализованы как методы с именем, основанным на имени типа. В имени метода TYPE заменяется на '_'.join(type(obj).__name__.split()). Отправка этим методам осуществляется с помощью repr1(). Методы, зависящие от типа, которые должны рекурсивно форматировать значение, должны вызывать self.repr1(subobj, level - 1).

Создание подклассов Repr объектов

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

import reprlib
import sys

class MyRepr(reprlib.Repr):

    def repr_TextIOWrapper(self, obj, level):
        if obj.name in {'<stdin>', '<stdout>', '<stderr>'}:
            return obj.name
        return repr(obj)

aRepr = MyRepr()
print(aRepr.repr(sys.stdin))         # распечатает '<stdin>'