repr python что это
Функции __str __() и __repr __() в Python
Мы рассмотрим две важные объектные функции в Python, которые очень полезны при отладке кода путем регистрации полезной информации об объекте.
__str __() в Python
Этот метод возвращает строковое представление объекта. Этот метод вызывается, когда для объекта вызывается функция print() или str().
Этот метод должен возвращать объект String. Если мы не реализуем функцию __str __() для класса, тогда используется встроенная реализация объекта, которая фактически вызывает функцию __repr __().
__repr __() в Python
Функция __repr __() возвращает представление объекта. Это может быть любое допустимое выражение в Python, такое как кортеж, словарь, строка и т.д.
Этот метод вызывается, когда для объекта используется функция repr(), в этом случае функция __repr __() должна возвращать String, иначе будет выдана ошибка.
Пример __str__ и __repr__ в Python
Обе эти функции используются при отладке, давайте посмотрим, что произойдет, если мы не определим эти функции для объекта.
Как видите, реализация по умолчанию бесполезна. Давайте продолжим и реализуем оба этих метода:
Обратите внимание, что мы возвращаем dict для функции __repr__. Посмотрим, что произойдет, если мы воспользуемся этими методами.
Обратите внимание, что функция repr() выдает ошибку TypeError, поскольку наша реализация __repr__ возвращает dict, а не строку.
Изменим реализацию функции __repr__ следующим образом:
Теперь он возвращает String, и новый вывод для вызовов представления объекта будет:
Ранее мы упоминали, что если мы не реализуем функцию __str__, то вызывается функция __repr__. Просто прокомментируйте реализацию функции __str__ из класса Person, и print (p) напечатает
Разница между функциями __str__ и __repr__
Заключение
Обе функции __str__ и __repr__ очень похожи. Мы можем получить представление объекта в формате String, а также в других конкретных форматах, таких как tuple и dict, чтобы получить информацию об объекте.
Магические методы: __str__, __repr__, __len__, __abs__
На этом занятии я расскажу о, так называемых, магических методах, которые предопределены в каждом классе и записываются через два подчеркивания вначале и в конце имен, например, так:
dunder-методами (от англ. сокращения double underscope)
Магические методы __str__ и __repr__
Чтобы лучше понять, как работают эти методы, объявим класс для описания кошек:
Если теперь перейти в консоль Python, импортировать этот класс из нашего текущего модуля ex1:
и создать его экземпляр:
то при выводе cat, увидим служебную информацию:
Если мы хотим ее как-то переопределить и отображать информацию в другом виде, формате, то как раз и используются магические методы __str__ и __repr__. Давайте для начала переопределим метод __repr__ и посмотрим как это отразится на выводе служебной информации о классе:
Обратите внимание, этот метод должен возвращать строку, поэтому здесь записан оператор return и формируемая строка. Что именно возвращать, мы решаем сами, в данном случае – это название класса и имя кошки.
Перезапустим консоль и снова импортируем измененный класс Cat. И, смотрите, теперь при создании экземпляра мы видим другую информацию при его выводе:
Как раз то, что определили в магическом методе __repr__. То же самое увидим и при использовании функции print и str. По идее, здесь должен отрабатывать другой магический метод __str__, но так как он у нас еще не переопределен, то автоматически выполняется метод __repr__.
Давайте добавим второй магический метод __str__ и посмотрим, как это повлияет на отображение данных:
Выполним повторное импортирование класса Cat, создадим его экземпляр и при отображении по ссылке:
по-прежнему будем видеть служебную информацию от метода __repr__. Однако, если выполнить отображение экземпляра класса через print или str, то будет срабатывать уже второй метод __str__. Вот в этом отличие этих двух магических методов.
Магические методы __len__ и __abs__
Их использование достаточно простое и очевидное. Давайте для примера представим, что у нас есть класс Point, который может хранить произвольный вектор координат точки и определим его так:
А, далее, по программе нам бы хотелось определять размерность координат с помощью функции len(), следующим образом:
Если сейчас запустить программу, то увидим ошибку, так как функция len не применима к экземплярам классов по умолчанию. Как вы уже догадались, чтобы изменить это поведение, можно переопределить магический метод __len__() и в нашем случае это можно сделать так:
Смотрите, мы здесь возвращаем размер списка __coords и если после этого запустить программу, то как раз это значение и будет выведено в консоль. То есть, магический метод __len__ указал, что нужно возвращать, в момент применения функции len() к экземпляру класса. Как видите, все просто и очевидно.
Следующий магический метод __abs__ работает аналогичным образом, только активируется в момент вызова функции abs для экземпляра класса, например, так:
Опять же, если сейчас выполнить программу, то увидим ошибку, т.к. функция abs не может быть напрямую применена к экземпляру. Но, если переопределить магический метод:
который возвращает список из абсолютных значений координат точки, то программа отработает в штатном режиме и мы увидим ожидаемый результат.
Вот так можно использовать эти два магических метода. Я, надеюсь, из этого занятия вы узнали, как применять четыре магических метода:
__str__, __repr__, __len__, __abs__
Видео по теме
#1: парадигма ООП, классы, экземпляры классов, атрибуты
#2: методы класса, параметр self, конструктор и деструктор
#4: объекты свойства (property) и дескрипторы классов
#5: статические свойства и методы классов, декоратор @staticmethod, создание синглетона
#6: простое наследование классов, режим доступа protected
#7: переопределение и перегрузка методов, абстрактные методы
#8: множественное наследование, функция super
#9: перегрузка операторов
#10: собственные исключения и итерабельные объекты
#11: функторы и менеджеры контекста
#12: нейронная сеть (пример реализации)
#14: полиморфизм в ООП на Python
#15: Моносостояние экземпляров класса
#16: Магические методы __str__, __repr__, __len__, __abs__
#17: Коллекция __slots__ для классов
#18: Как работает __slots__ с property и при наследовании классов
#19. Введение в обработку исключений
#20. Распространение исключений (propagation exceptions)
#21. Инструкция raise и пользовательские исключения
© 2021 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Чем отличается __repr__ от __str__?
Возьмем как пример парочку выдуманных классов:
1) Как следовало бы написать __repr__ и __str__ для этих классов?
И наоборот, как замену getstate, setstate можно придумать следующее:
а потом вызывать это:
1 ответ 1
datetime.date хорошо иллюстрирует разницу:
str(obj) возвращает читаемый текст. Для многих объектов имеет смысл определить __repr__() (так как реализация по умолчанию в object.__repr__ не слишком информативна). __str__() имеет смысл определять для объектов, для которых существует «естественное» человеко-читаемое (неспецифичное для Питона) представление (как в примере с датой), например, для логов.
Разные форматы рассчитаны на разного потребителя (человек/программа, Питон/общее назначение). Вот график, иллюстрирующий когда разные форматы удобно использовать:
1) Как следовало бы написать __repr__ и __str__ для этих классов?
Основной потребитель repr() это человек. Потребитель pickle.dumps() это как правило программа, например, multiprocessing использует pickle для обмена данными между процессами.
eval(repr(obj)) это подсказка, а не требование: если объект большой, то очевидно нужно сократить его представление. Во многих случаях, можно использовать многоточие:
Ещё раз: потребитель repr() —программист Питона, который видит это представление в REPL или debugger.
Документация говорит про случай, когда eval(repr(obj)) == obj не имеет смысла:
Этот специальный метод позволяет типу переопределить как format() себя ведёт, например:
Строковые представления экземпляров класса: методы __str__ и __repr__
Введение
Примеры
мотивация
Итак, вы только что создали свой первый класс в Python, аккуратный маленький класс, который инкапсулирует игральную карту:
В другом месте вашего кода вы создаете несколько экземпляров этого класса:
Вы даже создали список карт, чтобы представить «руку»:
Теперь, во время отладки, вы хотите посмотреть, как выглядит ваша рука, поэтому вы делаете то, что естественно, и пишете:
В замешательстве вы пытаетесь просто напечатать одну карту:
И снова, вы получите этот странный вывод:
Не бойся Мы собираемся это исправить.
Что на самом деле произошло, так это то, что вы попросили Python «выразить словами» суть этого объекта и затем показать его вам. Более явная версия того же механизма может быть:
В первой строке, вы пытаетесь превратить Card экземпляр в строку, а во втором вы его отображения.
Эта проблема
Решение (часть 1)
Рассмотрим следующий, обновленную версию нашего Card класса:
Возвращаясь к нашей проблеме отображения карты в более удобной для пользователя форме, если мы снова запустим:
Мы увидим, что наш вывод намного лучше:
Так здорово, мы закончили, верно?
Итак, мы перепроверили следующий код:
И, к нашему удивлению, мы снова получаем эти забавные шестнадцатеричные коды:
Решение (часть 2)
Ну, механизм закулисности немного отличается, когда Python хочет получить строковое представление элементов в списке. Оказывается, Python не заботится о __str__ для этой цели.
Теперь мы можем видеть, какой метод отвечает за каждый случай:
И кроме того, если определено, мы могли бы назвать методы напрямую (хотя это кажется немного неясным и ненужным):
Так, чтобы было ясно, рассмотрим следующую версию Card класса:
как это делают вызовы repr() :
Резюме
Реализованы оба метода, стиль eval-round-trip __repr __ ()
Синтаксис
Параметры
Примечания
Научим основам Python и Data Science на практике
Это не обычный теоритический курс, а онлайн-тренажер, с практикой на примерах рабочих задач, в котором вы можете учиться в любое удобное время 24/7. Вы получите реальный опыт, разрабатывая качественный код и анализируя реальные данные.
Функции repr() и str() в Python
Функция repr() возвращает печатное представление данного объекта.
Функция принимает единственный параметр:
Функция repr() возвращает печатаемую строку представления данного объекта.
Пример
Здесь мы присваиваем var значение foo. Затем функция repr() возвращает «foo», «foo» в двойных кавычках.
Когда результат repr() передается в eval(), мы получаем исходный объект (для многих типов).
Пример 2: реализовать __repr __() для настраиваемых объектов
Внутренне функция repr() вызывает __repr __() данного объекта.
Вы можете легко реализовать / переопределить __repr __(), чтобы repr() работал по-другому.
Функция str() возвращает строковую версию данного объекта.
Метод str() принимает три параметра:
Есть шесть типов ошибок:
Возвращаемое значение из str()
Метод str() возвращает строку, которая считается неформальным или хорошо печатаемым представлением данного объекта.
Пример 1: преобразовать в строку
Если параметр кодирования и ошибок не указан, str() внутренне вызывает метод __str __() объекта.
Если он не может найти метод __str __(), вместо этого он вызывает repr (obj).
Примечание: переменная результата будет содержать строку.
Также попробуйте эти команды на консоли Python.
Пример 2: Как str() работает с байтами?
Если указан параметр кодирования и ошибок, первый параметр, объект, должен быть байтовым объектом (байтами или байтовым массивом).
Если объект представляет собой байты или массив байтов, str() внутренне вызывает bytes.decode (кодирование, ошибки).
В противном случае он получает объект байтов в буфере перед вызовом метода decode().
Здесь символ «ö» не может быть декодирован с помощью ASCII. Следовательно, он должен выдать ошибку. Однако мы установили error = ‘ignore’. Следовательно, Python игнорирует символ, который не может быть декодирован с помощью str().