В чем цель __str__ и __repr__? - программирование
Подтвердить что ты не робот

В чем цель __str__ и __repr__?

Я действительно не понимаю, где используются __str__ и __repr__, используемые в Python. Я имею в виду, я получаю, что __str__ возвращает строковое представление объекта. Но зачем мне это нужно? В каком сценарии использования? Кроме того, я читал об использовании __repr__

Но я не понимаю, где бы я их использовал?

4b9b3361

Ответ 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