Naprawdę nie rozumiem, gdzie są __str__
i __repr__
używane w Pythonie. Mam na myśli, że __str__
zwraca reprezentację ciągu obiektu. Ale dlaczego miałbym tego potrzebować? W jakim scenariuszu użycia? Czytałem też o używaniu__repr__
Ale nie rozumiem, gdzie bym ich użył?
__str__
=to_s
i__repr__
=inspect
.Odpowiedzi:
__repr__
__str__
Użyj,
__str__
jeśli masz klasę i będziesz potrzebować informacji / nieformalnych danych wyjściowych, ilekroć używasz tego obiektu jako części ciągu. Np. Możesz zdefiniować__str__
metody dla modeli Django, które są następnie renderowane w interfejsie administracyjnym Django. Zamiast czegoś takiego<Model object>
jak imię i nazwisko osoby, nazwa i data wydarzenia itp.__repr__
i__str__
są podobne, w rzeczywistości czasami równe (przykład zBaseSet
klasysets.py
z biblioteki standardowej):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__
źródło
__repr__
zamiast__str__
django?Jedynym miejscem, w którym często używasz ich obu, jest sesja interaktywna. Jeśli wydrukujesz obiekt
__str__
, zostanie wywołana jego metoda, podczas gdy jeśli użyjesz samego obiektu,__repr__
zostanie wyświetlony:>>> from decimal import Decimal >>> a = Decimal(1.25) >>> print(a) 1.25 <---- this is from __str__ >>> a Decimal('1.25') <---- this is from __repr__
Ma
__str__
być jak najbardziej czytelny dla człowieka, podczas gdy__repr__
celem powinno być coś, co można wykorzystać do odtworzenia obiektu, chociaż często nie będzie dokładnie tak, jak został stworzony, jak w tym przypadku.Nie jest też niczym niezwykłym w przypadku obu
__str__
i__repr__
zwracania tej samej wartości (na pewno w przypadku typów wbudowanych).źródło
Konik polny, jeśli masz wątpliwości, idź na górę i przeczytaj starożytne teksty . W nich znajdziesz, że __repr __ () powinien:
źródło
__repr__
, że oficjalna dokumentacja tak naprawdę nie odpowiada na pytanie, dlaczego go używasz, a tylko dlatego, że odpowiedź na pytanie jest gdzie indziej, nie jest dobrym powodem, aby tego również nie było odpowiedź na SO (tak często, jak nie Google, sprowadzi cię tu z powrotem!) Jeśli nie uważasz, że pytanie jest warte odpowiedzi, nie możesz po prostu na nie odpowiedzieć, chociaż w tym przypadku zgadzam się, że jest już dobrze omówiony Tak więc powiązanie z duplikatami byłoby właściwą odpowiedzią.Opierając się na poprzednich odpowiedziach i pokazując więcej przykładów. Przy prawidłowym użyciu różnica między
str
irepr
jest wyraźna. W skrócierepr
należy zwrócić ciąg znaków, który może być wklejony do kopiowania przebudowany dokładny stan obiektu, natomiaststr
jest przydatny dologging
iobserving
debugowanie wyników. Oto kilka przykładów pokazujących różne wyniki dla niektórych znanych bibliotek.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
Dobrze
str
jest wydrukować do pliku dziennika, gdzierepr
można go zmienić, jeśli chcesz go uruchomić bezpośrednio lub zrzucić jako polecenia do pliku.x = datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)
Odrętwiały
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]
w Numpy
repr
jest ponownie bezpośrednio zużywalny.Przykład niestandardowego 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)
W tym przykładzie
repr
zwraca ponownie ciąg, który może być bezpośrednio używany / wykonywany, alestr
jest bardziej przydatny jako wyjście debugowania.v = Vector3([1,2,3]) print str(v) #x: 1, y: 2, z: 3 print repr(v) #Vector3([1,2,3])
źródło
Miejmy klasę bez
__str__
funkcji.class Employee: def __init__(self, first, last, pay): self.first = first self.last = last self.pay = pay emp1 = Employee('Ivan', 'Smith', 90000) print(emp1)
Kiedy drukujemy to wystąpienie klasy,
emp1
otrzymujemy:<__main__.Employee object at 0x7ff6fc0a0e48>
Nie jest to zbyt pomocne, a na pewno nie jest to, co chcemy wydrukować, jeśli używamy go do wyświetlania (jak w html)
Więc teraz ta sama klasa, ale z
__str__
funkcją: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)
Teraz zamiast wypisywać, że istnieje obiekt, otrzymujemy to, co określiliśmy zwracając
__str__
funkcję:The employee John Williams earns 90000
źródło
str
będzie miał nieformalny i czytelny format, a jednocześnierepr
zapewni oficjalną reprezentację obiektu.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
źródło
str i repr są sposobami reprezentacji. Możesz ich używać podczas pisania zajęć.
class Fraction: def __init__(self, n, d): self.n = n self.d = d def __repr__(self): return "{}/{}".format(self.n, self.d)
na przykład kiedy drukuję jej egzemplarz, zwraca rzeczy.
print(Fraction(1, 2))
prowadzi do
1/2
podczas
class Fraction: def __init__(self, n, d): self.n = n self.d = d def __str__(self): return "{}/{}".format(self.n, self.d) print(Fraction(1, 2))
skutkuje również
1/2
Ale co, jeśli napiszesz oba z nich, z których korzysta Python?
class Fraction: def __init__(self, n, d): self.n = n self.d = d def __str__(self): return "str" def __repr__(self): return "repr" print(Fraction(None, None))
To skutkuje
str
Więc python w rzeczywistości używa metody str , a nie metody repr , gdy oba są zapisywane.
źródło
Załóżmy, że masz klasę i chcesz sprawdzić instancję, a wydruk nie zawiera zbyt wielu przydatnych informacji
class Person: def __init__(self, name, age): self.name = name self.age = age p1 = Person("John", 36) print(p1) # <__main__.Animal object at 0x7f9060250410>
Teraz zobacz klasę ze str , która pokazuje informacje o instancji, a przy repr nawet nie potrzebujesz print. Nieźle, nie?
class Animal: def __init__(self, color, age, breed): self.color = color self.age = age self.breed = breed def __str__(self): return f"{self.color} {self.breed} of age {self.age}" def __repr__(self): return f"repr : {self.color} {self.breed} of age {self.age}" a1 = Animal("Red", 36, "Dog") a1 # repr : Red Dog of age 36 print(a1) # Red Dog of age 36
źródło