Обычные или pythoni c __repr__ методы - PullRequest
4 голосов
/ 29 января 2020

Я обычно пишу __repr__ как способ показать, как экземпляр может быть воссоздан в первую очередь. Например:

class Component:
    def __init__(self, start, end):
        self.start = start
        self.end = end
    def __repr__(self):
        return f'{self.__class__.__name__}(start={self.start}, end={self.end})'

Существует ли «стандартный» способ написания __repr__, если нет, предлагаются ли варианты / рекомендации по написанию этого текста, или это полностью субъективно?

1 Ответ

5 голосов
/ 29 января 2020

Общее правило, если это вообще возможно, производит вывод, который может быть напечатан для воссоздания объекта; из документов :

Если это вообще возможно, это должно выглядеть как действительное выражение Python, которое можно использовать для воссоздания объекта с тем же значением (при условии соответствующей среды). Если это невозможно, должна быть возвращена строка вида <... некоторое полезное описание ...>.

Вторая часть этого правила в основном там, чтобы убедиться, что вы не не создавать что-то, что выглядит как каноническое воссоздание репр; на практике я не видел, чтобы это следовало неукоснительно.

Для вашего конкретного случая c я бы порекомендовал только два твика:

  1. Если Component может содержать другой Component в качестве значения start или end, украсьте __repr__ с помощью reprlib.recursive_repr, чтобы избежать возможности бесконечной рекурсии в случае содержащего себя Component (важно для библиотек где это может произойти независимо от намерений автора библиотеки)
  2. Явно используйте repr ваших атрибутов с модификатором !r (вам не нужна «дружественная человеку» строка, которую вы хотите представление), изменив строку на:

    return f'{self.__class__.__name__}(start={self.start!r}, end={self.end!r})'
    
...