Cпеціальні методи __str__() та __repr__(), визначають яким чином об’єкт має відображатись у вигляді рядка (іншими словами його рядкове представлення). Це може бути корисним для налагодження програм і ведення журналів (логування), роблячи їх більш зрозумілими в процесі розробки.

  • __str__(): цей метод об’єкта викликається функцією print() та вбудованою функцією str(). Його призначення – повертати зручне, читабельне та зрозуміле для користувача рядкове представлення об’єкта.
  • __repr__(): цей метод об’єкта викликається вбудованою функцією repr(), під час друку об’єкта в консолі без явного виклику print(), або замість __str__() (якщо __str__() для об’єкта не визначено). В ідеалі, метод __repr__() повинен повертати рядок, який в разі передачі в функцію eval(), дозволить створити об’єкт зі вказаними властивостями. Таким чином, він більше орієнтований на розробників і налагодження, пропонуючи машино-читабельне представлення об’єкта.

Приклади використання __str__() та __repr__()

Для початку створимо простий клас Product, і подивимось як виглядає рядкове представлення його об’єкту, якщо не зробити перевизначення методів __str__() та __repr__():

class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price


product = Product('banana', 100)

# Using print() or str() calls __str__()
print(product)
# <__main__.Product object at 0x0000022BF7D44F40>

# Using repr() or printing in the console calls __repr__()
print(repr(product))
# <__main__.Product object at 0x0000022BF7D44F40>

В прикладі вище, для друку об’єкта Product використовується реалізація __str__() та __repr__() за замовчуванням (що має не дружній малоінформативний формат). Для отримання рядка необхідного формату, додаю власну реалізацію __str__() та __repr__() до класу Product:

class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def __str__(self):
        return f"Product(name={self.name}, price={self.price})"

    def __repr__(self):
        return f"Product('{self.name}', {self.price})"


product = Product('banana', 100)

# Using print() or str() calls __str__()
print(product)
# Product(name=banana, price=100)

# Using repr() or printing in the console calls __repr__()
print(repr(product))
# Product('banana', 100)

Тепер результат друку об’єкта Product має більш дружній та інформативний формат.

Спробуємо створити об’єкт Product використовуючи функції repr() та eval() (зверніть увагу на реалізацію __repr__ в моєму класі вище):

product = Product('banana', 100)

new_product = eval(repr(product))
print(new_product)
# Product(name=banana, price=100)

Як видно з результату, об’єкт було успішно створено.

У цьому прикладі, __str__() надає зручне для користувача рядкове представлення об’єкта Product, тоді як __repr__() надає більш формальне представлення, яке може бути використано для відтворення об’єкта, що полегшує налагодження та розробку.

Підсумок

  • реалізація __str__() може бути корисною, коли є необхідність у зручному для користувача представленні об’єкта
  • реалізація __repr__() для будь-якого класу, котрий ви розробляєте, є хорошою практикою розробки, що покращує можливість налагодження вашого коду

Мітки: