← Lekcje
Python · lekcja 28

Klasy i obiekty 1: klasa, konstruktor, metody

Dane i czynności w jednym miejscu: tak powstaje obiekt.

  1. Po co klasa, skoro mamy słownik
  2. Definicja klasy i konstruktor __init__
  3. Słowo self i tworzenie obiektów
  4. Metody: jedna liczy wynik, druga zmienia dane
Rozgrzewka · 3 minuty

Co pamiętacie z poprzedniej lekcji?

  1. Co robi random.randint(1, 100) w grze w zgadywanie?
  2. Jak w pętli while policzyć, ile prób zrobił gracz?
  3. Co odda student["grades"], gdy student = {"name": "Ala", "grades": [5, 4, 3]}?
Część 1 · Po co klasa

Słownik trzyma dane, klasa trzyma dane i czynności

Słownik z lekcji 14 dobrze trzyma dane, ale sam nic nie umie. Średnią liczy osobna funkcja obok i trzeba pamiętać, żeby podać jej właściwy słownik. Klasa łączy jedno z drugim: dane i czynności siedzą w tym samym miejscu.

Słownik: same dane name: „Ala” grades: [5, 4, 3] średnia: funkcja gdzieś obok Obiekt: dane i czynności name: „Ala” grades: [5, 4, 3] average() i add_grade() w środku

Porównanie z życia: klasa to pusty formularz, który mówi, jakie rubryki ma mieć każdy uczeń. Obiekt to jedna wypełniona kartka. Formularz jest jeden, kartek może być trzydzieści.

docs.python.org, The Python Tutorial, rozdz. 9.3 (A First Look at Classes)
Część 1 · Definicja klasy

Słowo class i konstruktor

class Student:

    def __init__(self, name, grades):
        self.name = name
        self.grades = grades
  • class zaczyna opis, nazwa idzie wielką literą: Student, nie student.
  • Po dwukropku wszystko, co należy do klasy, stoi wcięte o cztery spacje.
  • __init__ to konstruktor: Python uruchamia go sam przy tworzeniu obiektu.
  • self.name = name zapisuje to z nawiasu do środka nowego obiektu.

Skąd nazwa: init to skrót od angielskiego „initialize”, czyli „ustaw wartości początkowe”. Dwa podkreślniki z obu stron to znak nazwy zarezerwowanej dla Pythona.

docs.python.org, The Python Tutorial, rozdz. 9.3.1 (Class Definition Syntax) · rozdz. 9.3.2 (Class Objects) · PEP 8 (Naming Conventions)
Część 2 · Słowo self

Skąd metoda wie, o który obiekt chodzi?

self to ten obiekt, na którym właśnie pracujemy. W życiu mówicie „moje oceny”, a nie „oceny Ali”, choć chodzi o te same oceny. Metoda robi tak samo: self.grades znaczy „oceny tego ucznia, po którego kropce mnie wywołano”.

piszecie ala.average() Python dokłada obiekt sam Python wykonuje Student.average(ala) obiekt przed kropką wchodzi na pierwsze miejsce, czyli pod nazwę self

Dlatego self stoi pierwszy w nawiasie każdej metody, a przy wywołaniu go nie wpisujecie: obiekt wskazała już kropka.

docs.python.org, The Python Tutorial, rozdz. 9.3.4 (Method Objects)
Część 2 · Tworzenie obiektów

Jedna klasa, dwa osobne komplety danych

ala = Student("Ala", [5, 4, 3])
bartek = Student("Bartek", [3, 3, 4])

print(ala.name)
print(bartek.name)
print(ala.grades)
print(bartek.grades)
Ala
Bartek
[5, 4, 3]
[3, 3, 4]
ala name: „Ala” · grades: [5, 4, 3] bartek name: „Bartek” · grades: [3, 3, 4] osobno
docs.python.org, The Python Tutorial, rozdz. 9.3.2 (Class Objects)
Część 2 · Atrybuty i kropka

Kropka czyta i zmienia

print(ala.name)
ala.grades.append(6)
print(ala.grades)
ala.name = "Alicja"
print(ala.name)
print(bartek.grades)
Ala
[5, 4, 3, 6]
Alicja
[3, 3, 4]
  • ala.name po prawej stronie czyta, po lewej stronie zapisuje.
  • ala.grades to zwykła lista, więc działa na niej append z lekcji 9.
docs.python.org, The Python Tutorial, rozdz. 9.3.3 (Instance Objects)
Część 3 · Metody

Jedna oddaje wynik, druga zmienia dane

class Student:

    def __init__(self, name, grades):
        self.name = name
        self.grades = grades

    def average(self):
        return sum(self.grades) / len(self.grades)

    def add_grade(self, grade):
        self.grades.append(grade)
ala = Student("Ala", [5, 4, 3])

print(ala.average())
ala.add_grade(6)
print(ala.average())
4.0
4.5
  • average liczy i oddaje wynik przez return, danych nie rusza.
  • add_grade dopisuje ocenę do obiektu i nic nie oddaje.
docs.python.org, The Python Tutorial, rozdz. 9.3.4 (Method Objects) · PEP 8 (Naming Conventions)
Część 3 · Trzy typowe błędy

Co Python wypisze przy pomyłce

Co napisanoKomunikat PythonaCo znaczy
def average(): bez selfTypeError: Student.average() takes 0 positional arguments but 1 was givenPython podał obiekt, a metoda nie ma dla niego miejsca
ala = Student("Ala")TypeError: Student.__init__() missing 1 required positional argument: 'grades'Konstruktor czeka na dwie dane, dostał jedną
print(ala.nmae)AttributeError: 'Student' object has no attribute 'nmae'Literówka w nazwie atrybutu, obiekt takiego nie ma
Ćwiczenie · przy komputerze · 10 minut

Ćwiczenie: klasa Product

  1. Utwórz plik products.py. Napisz klasę Product z konstruktorem, który przyjmuje name i price. Zrób dwa obiekty: book za 12 i bag za 180. Wypisz nazwę i cenę każdego.
  2. Dopisz metodę price_with_tax, która oddaje cenę powiększoną o podatek 23 procent, zaokrągloną do dwóch miejsc. Wypisz wynik dla obu produktów.
  3. Dopisz metodę describe, która oddaje jeden napis z nazwą, ceną i ceną z podatkiem. Wypisz opis obu produktów, potem zmień kropką cenę obiektu bag na 150 i wypisz opis jeszcze raz.
Jak sprawdzić, czy wynik jest dobry

W zadaniu 3 opis po zmianie ceny musi pokazać nową liczbę. Jeśli pokazuje starą, wywołaliście describe przed zmianą. Gdy zobaczycie TypeError, sprawdźcie, czy każda metoda ma self na pierwszym miejscu w nawiasie.

Sprawdzenie

Trzy pytania na koniec

  1. Czym klasa różni się od obiektu?
  2. Dlaczego self stoi pierwszy w nawiasie metody, a przy wywołaniu go nie podajemy?
  3. Czym konstruktor różni się od zwykłej metody?
Podsumowanie

A jak to wygląda w produkcji?

Na lekcjiW produkcjiStatus
Klasa StudentW dzienniku elektronicznym osobne klasy opisują ucznia, lekcję, ocenę i nauczycielacodziennie
Konstruktor __init__Nowe zamówienie w sklepie powstaje jako obiekt z datą, klientem i listą pozycji ustawionymi na starciecodziennie
Metoda z returnCena z podatkiem, rabat i koszt wysyłki: każda z tych liczb ma w sklepie własną metodęstandard w firmach
Wiele obiektów jednej klasyLista obiektów w jednej zmiennej i własny wygląd obiektu przy printna następnej lekcji