Bez tej metody print wypisuje nazwę klasy i adres obiektu w pamięci, czyli numer, który za każdym uruchomieniem jest inny. Metoda __str__ oddaje napis, który ma się pokazać zamiast tego adresu. print woła ją sam, nie trzeba jej wywoływać.
Skąd nazwa: metody z dwoma podkreślnikami z obu stron Python woła sam w odpowiednim momencie. Tak samo __init__ uruchamia się przy tworzeniu obiektu, a __str__ przy wypisywaniu.
docs.python.org, The Python Language Reference, rozdz. 3.3.1 (Basic customization, object.__str__)
Część 3 · Obiekt w obiekcie
Atrybutem może być lista innych obiektów
class SchoolClass:
def __init__(self, name):
self.name = name
self.students = []
def add_student(self, student):
self.students.append(student)
def best_student(self):
best = self.students[0]
for student in self.students:
if student.average() > best.average():
best = student
return best
W klasie pochodnej brakuje super().__init__(name, grades)
AttributeError: 'Athlete' object has no attribute 'name'
Pierwsza linia w __init__ klasy pochodnej to wywołanie super()
print(student), a klasa nie ma __str__
<__main__.Student object at 0x105e06120>
Dopisz __str__ albo wypisuj pojedyncze atrybuty
Metoda wywołana na liście: students.average()
AttributeError: 'list' object has no attribute 'average'
Metodę ma obiekt, nie lista: students[0].average()
Adres 0x105e06120 u Was będzie inny: to numer miejsca w pamięci, losowany przy każdym uruchomieniu.
Ćwiczenie · przy komputerze · 10 minut
Ćwiczenie: produkty i koszyk
Załóż plik shop.py. Zacznij od klasy Product z lekcji 28: atrybuty name i price oraz metoda price_with_tax, która oddaje cenę razy 1.23 zaokrągloną do dwóch miejsc.
Utwórz dwa produkty: Zeszyt za 12 i Plecak za 180. Wypisz nazwę i cenę z podatkiem każdego z nich.
Napisz klasę Cart: w __init__ pusta lista products, metoda add dokłada produkt, metoda total sumuje ceny z podatkiem. Dodaj oba produkty i wypisz sumę.
Dla chętnych: dopisz class DiscountedProduct(Product) z atrybutem discount w procentach i własną wersją price_with_tax. Dodaj Linijkę za 4 z rabatem 25 do koszyka.
Wskazówka
Metodę __str__ w klasie Cart możesz napisać tak, żeby print(cart) dawało Koszyk: 2 produkty za 236.16. Gdy suma wychodzi dziwnie długa, brakuje round(result, 2) w total.
Sprawdzenie
Trzy pytania na koniec
Dlaczego w pętli piszemy student.average(), a nie students.average()?
Co daje klasie metoda __str__?
Co klasa pochodna dostaje od klasy bazowej i po co woła super()?
Podsumowanie
A jak to wygląda w produkcji?
Na lekcji
W produkcji
Status
Lista obiektów w programie
Sklep trzyma produkty w bazie danych, a program wczytuje je do listy obiektów i dalej robi to samo
codziennie
Metoda __str__
W zapisie zdarzeń każdy obiekt wypisuje się jednym krótkim wierszem, żeby dało się czytać dziennik programu
codziennie
Atrybut _discount z podkreślnikiem
Podkreślnik na początku nazwy to umowa: „to wnętrze klasy, nie ruszaj z zewnątrz”, choć Python niczego nie blokuje
standard w firmach
Dziedziczenie jednej klasy
Gotowe biblioteki dają klasę bazową, a firma dopisuje własną pochodną z dwiema, trzema metodami