August 2, 2018

Разница между __str__ и __repr__

Во многих курсах по Python упоминают только один из этих двух "магических" методов и применяют их для одной цели: превращение объекта в строку. Считаю такой подход неправильным и поэтому расскажу, когда какой метод стоит применять.

Примером для дальнейшего описания послужит простенький класс точки на плоскости:

class Point:                                   
  def __init__(self, x, y):                          
    self.x = x                                
    self.y = y 

Давайте, для начала, определим метод __str__ у нашего класса и посмотрим, что выйдет

class Point:                                   
  def __init__(self, x, y):                          
    self.x = x                                
    self.y = y                                
                                         
  def __str__(self, x, y):                           
    return "Point, x={}, y={}".format(x, y)

point = Point(1, 2)
print(point) 

Как мы и ожидаем увидеть, вывод будет следующим:

Point, x=1, y=2

Загвоздка в том, что если мы переименуем __str__ в __repr__, то в выводе изменится... ровно ничего. А теперь давайте определим и тот и другой, но немного по-разному.

class Point:                                   
  def __init__(self, x, y):                          
    self.x = x                                
    self.y = y                                
                                         
  def __repr__(self):                             
    return "repr: Point, x={}, y={}".format(self.x, self.y)         
                                         
  def __str__(self):                              
    return "str: Point, x={}, y={}".format(self.x, self.y)          
                                         
point = Point(5, 6)                               
print(point) 

Вывод будет следующим:

str: Point, x=5, y=6

Значит, при превращении объекта в строку, преимущество имеет __str__, да и его название говорит о том, что это и есть его назначение. Но зачем тогда нужен точно такой же __repr__? Суть в том, что не такой же. Откройте интерпретатор и вставьте туда наш класс. А теперь введите

point = Point(1, 2)
point

Выводом послужит следующая строка:

repr: Point, x=1, y=2

То есть для того, чтобы выводить объект в интерпретаторе, преимущество имеет repr.

Вывод: используйте __str__ для превращения объекта в строку, а __repr__, когда хотите получать какую-то информацию в интерпретаторе при дебаге. Да, они взаимозаменяемы, но созданы они для разных целей.

Тем временем наше маленькое расследование подошло к концу.

Буду рад, если вы подпишетесь на мою группу SnakeBlog