В чем цель __str__ и __repr__?
Я действительно не понимаю, где используются __str__
и __repr__
, используемые в Python. Я имею в виду, я получаю, что __str__
возвращает строковое представление объекта. Но зачем мне это нужно? В каком сценарии использования? Кроме того, я читал об использовании __repr__
Но я не понимаю, где бы я их использовал?
Ответы
Ответ 1
__repr__
Вызывается встроенной функцией repr()
и строковыми преобразованиями (обратными кавычками) для вычисления "официального" строкового представления объекта. Если это вообще возможно, это должно выглядеть как действительное выражение Python, которое может быть использовано для воссоздания объекта с тем же значением (с учетом соответствующей среды).
__str__
Вызывается встроенной функцией str()
и оператором печати для вычисления "неформального" строкового представления объекта.
Используйте __str__
, если у вас есть класс, и вам понадобится информативный/неформальный вывод, всякий раз, когда вы используете этот объект как часть строки. Например. вы можете определить методы __str__
для моделей Django, которые затем отображаются в интерфейсе администрирования Django. Вместо того, чтобы что-то вроде <Model object>
, вы получите как имя и фамилию человека, имя и дату события и т.д.
__repr__
и __str__
аналогичны, на самом деле иногда равны (пример из BaseSet
класса в sets.py
из стандартной библиотеки):
def __repr__(self):
"""Return string representation of a set.
This looks like 'Set([<list of elements>])'.
"""
return self._repr()
# __str__ is the same as __repr__
__str__ = __repr__
Ответ 2
Единственное место, где вы их используете, - это интерактивный сеанс. Если вы печатаете объект, тогда его вызов будет вызываться его метод __str__
, тогда как если вы просто используете объект сам по себе, отображается его __repr__
:
>>> from decimal import Decimal
>>> a = Decimal(1.25)
>>> print(a)
1.25 <---- this is from __str__
>>> a
Decimal('1.25') <---- this is from __repr__
__str__
призван быть максимально понятным для человека, тогда как __repr__
должен быть тем, что можно было бы использовать для воссоздания объекта, хотя часто не будет точно, как он был создан, как в этом случае.
Также не редко, как для __str__
, так и для __repr__
возвращать одно и то же значение (конечно, для встроенных типов).
Ответ 3
Кузнечик, если он сомневается перейти на гору и прочитать Древний Тексты. В них вы обнаружите, что __repr __() должен:
Если это вообще возможно, это должно выглядеть как действительное выражение Python, которое может быть использовано для воссоздания объекта с тем же значением.
Ответ 4
Построение и предыдущие ответы и еще несколько примеров. При правильном использовании разница между str
и repr
понятна. Короче говоря, repr
должен возвращать строку, которая может быть скопирована для восстановления точного состояния объекта, тогда как str
полезна для logging
и observing
результатов отладки. Вот несколько примеров, чтобы увидеть различные результаты для некоторых известных библиотек.
Datetime
print repr(datetime.now()) #datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)
print str(datetime.now()) #2017-12-12 18:49:27.134452
str
хороша для печати в файл журнала, где по мере того, как repr
может быть переназначен, если вы хотите запустить его напрямую или выгрузить его в виде команд в файл.
x = datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)
Numpy
print repr(np.array([1,2,3,4,5])) #array([1, 2, 3, 4, 5])
print str(np.array([1,2,3,4,5])) #[1 2 3 4 5]
в Numpy repr
снова непосредственно расходная.
Пользовательский пример Vector3
class Vector3(object):
def __init__(self, args):
self.x = args[0]
self.y = args[1]
self.z = args[2]
def __str__(self):
return "x: {0}, y: {1}, z: {2}".format(self.x, self.y, self.z)
def __repr__(self):
return "Vector3([{0},{1},{2}])".format(self.x, self.y, self.z)
В этом примере repr
снова возвращает строку, которая может быть непосредственно использована/выполнена, тогда как str
более полезна в качестве отладочного вывода.
v = Vector3([1,2,3])
print str(v) #x: 1, y: 2, z: 3
print repr(v) #Vector3([1,2,3])
Одна вещь, о которой нужно помнить, если str
не определена, а repr
, str
будет автоматически вызывать repr
. Таким образом, это всегда хорошо, по крайней мере, определить repr
Ответ 5
str
будет неофициальным и читаемым форматом, тогда как repr
даст официальное представление объекта.
class Complex:
# Constructor
def __init__(self, real, imag):
self.real = real
self.imag = imag
# "official" string representation of an object
def __repr__(self):
return 'Rational(%s, %s)' % (self.real, self.imag)
# "informal" string representation of an object (readable)
def __str__(self):
return '%s + i%s' % (self.real, self.imag)
t = Complex(10, 20)
print (t) # this is usual way we print the object
print (str(t)) # this is str representation of object
print (repr(t)) # this is repr representation of object
Answers :
Rational(10, 20) # usual representation
10 + i20 # str representation
Rational(10, 20) # repr representation
Ответ 6
Давайте иметь класс без функции __str__
.
class Employee:
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.pay = pay
emp1 = Employee('Ivan', 'Smith', 90000)
print(emp1)
Когда мы печатаем этот экземпляр класса emp1
, мы получаем следующее:
<__main__.Employee object at 0x7ff6fc0a0e48>
Это не очень полезно, и, конечно, это не то, что мы хотим напечатать, если мы используем его для отображения (как в html)
Итак, теперь тот же класс, но с функцией __str__
:
class Employee:
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.pay = pay
def __str__(self):
return(f"The employee {self.first} {self.last} earns {self.pay}.")
# you can edit this and use any attributes of the class
emp2 = Employee('John', 'Williams', 90000)
print(emp2)
Теперь вместо того, чтобы печатать, что есть объект, мы получаем то, что мы указали с возвратом функции __str__
:
The employee John Williams earns 90000