• Programowanie
  • Klasy w Pythonie bez pułapek - self, instancje i dataclass

Klasy w Pythonie bez pułapek - self, instancje i dataclass

Tymoteusz Maciejewski • 9 listopada 2026
Logo Pythona i napis "Konstruktor Klasy". Szkoła DevNet zaprasza na wtorki z Pythonem.

Spis treści

Masz kilka zadań do wykonania, a każde ma własny status, dane i metodę zmiany stanu. Klasa w Pythonie zwykle dobrze porządkuje taki kod, choć przy jednym prostym rekordzie słownik może być lżejszym wyborem.

Schemat ilustrujący klasę

Klasa łączy stan obiektu z operacjami, które na nim wykonujesz

  • Klasa opisuje wspólną strukturę i zachowanie obiektów.
  • Instancja to pojedynczy obiekt utworzony na podstawie klasy.
  • self wskazuje instancję, na której działa metoda.
  • Dataclass ogranicza powtarzalny kod, gdy obiekt głównie przechowuje dane.
  • Słownik często wystarczy, gdy struktura danych jest mała lub zmienna.

Klasa opisuje typ obiektu, a instancja przechowuje własny stan

Wyobraź sobie dwa zadania o tym samym zestawie pól: nazwie i statusie. Klasa opisuje, jakie dane i operacje mają być dostępne, a każda utworzona instancja przechowuje własne wartości.

W definicji zapisujesz metody, czyli funkcje związane z klasą. Gdy wywołujesz metodę przez obiekt, Python przekazuje tę instancję jako pierwszy argument. Dlatego job.finish() można rozumieć jako wywołanie Job.finish(job), co opisuje oficjalny samouczek Pythona.

Ten mechanizm sprawia, że metoda może zmieniać stan właściwego obiektu. Bez tej więzi łatwo skończyć z funkcjami, którym za każdym razem trzeba przekazywać ten sam zestaw powiązanych danych.

Wystarczą trzy elementy, żeby utworzyć i użyć obiektu

Najprostsza klasa potrzebuje nazwy, metody __init__ ustawiającej początkowe dane oraz metody opisującej działanie obiektu. W przykładzie zadanie zmienia status z „oczekujące” na „gotowe”.

class Job:
    def __init__(self, name):
        self.name = name
        self.status = "oczekujące"

    def finish(self):
        self.status = "gotowe"

job = Job("Raport")
job.finish()

print(job.name)    # Raport
print(job.status)  # gotowe

self nie jest specjalnym słowem kluczowym. To powszechnie używana nazwa pierwszego argumentu metody, którą opisuje FAQ dokumentacji Pythona. Mimo że technicznie można wybrać inną nazwę, trzymaj się self, bo dzięki temu kod jest czytelny dla innych osób.

Jest tu też pułapka, która ujawnia się dopiero przy kilku obiektach. Jeśli lista miałaby być atrybutem klasy, a nie instancji, wszystkie obiekty mogłyby współdzielić tę samą listę:

class Job:
    tags = []  # wspólna lista dla instancji tej klasy

Gdy każda instancja ma mieć osobne tagi, twórz listę w __init__: self.tags = []. Atrybuty zmienne, takie jak listy i słowniki, szczególnie łatwo przypadkiem współdzielić.

Wybierz klasę wtedy, gdy dane i metody tworzą jeden model

Jeśli masz tylko chwilowy zestaw pól, klasa może dołożyć ceremonii zamiast porządku. Praktyczna granica jest prosta: użyj słownika dla danych o zmiennym kształcie, a klasy wtedy, gdy chcesz połączyć ustalone dane z zachowaniem obiektu.

Sytuacja Co wybrać Dlaczego
Jednorazowe dane, których pola mogą się zmieniać dict Możesz dodawać i usuwać klucze bez zmieniania definicji typu.
Stały zestaw pól, głównie do przechowywania danych @dataclass Dekorator generuje część powtarzalnych metod, między innymi inicjalizację i reprezentację obiektu.
Obiekt ma pilnować reguł lub wykonywać operacje na swoim stanie Zwykła klasa Samodzielnie określasz, jak obiekt powstaje i jak wolno zmieniać jego stan.

Wbudowany moduł dataclasses pozwala zapisać klasę z polami bez ręcznego tworzenia części typowych metod. Dokumentacja modułu dataclasses opisuje między innymi generowanie inicjalizacji, porównywania i tekstowej reprezentacji. Pamiętaj jednak, że sama adnotacja typu, taka jak name: str, nie zastępuje walidacji danych.

Przyznam, że do prostego obiektu przenoszącego dane wybrałbym dataclass, a do obiektu pilnującego reguł, takiego jak zadanie z dozwolonymi przejściami statusu, zwykłą klasę. Słownik zostawiłbym dla danych, których struktura naprawdę może się zmieniać.

Gdy stan obiektu nie zmienia się poprawnie, sprawdź miejsce przypisania

Dwa obiekty zachowują się tak, jakby były jednym? Najpierw sprawdź, czy zmienna, którą zmieniasz, należy do instancji, czy została zdefiniowana na poziomie klasy.

Sytuacja Prawdopodobna przyczyna Co zrobić
Zmiana listy w jednym obiekcie wpływa na drugi Lista jest atrybutem klasy i jest współdzielona. Utwórz ją w __init__ przez przypisanie do self.
Wywołanie job.finish() zgłasza błąd brakującego argumentu Metoda może nie przyjmować self w definicji. Dodaj self jako pierwszy parametr metody instancji.
Wartość pola nie pojawia się po utworzeniu obiektu Przypisanie mogło trafić do zmiennej lokalnej zamiast do atrybutu instancji. W __init__ przypisz wartość do self.nazwa_pola.

Jeśli metoda ma działać bez konkretnej instancji, sprawdź, czy potrzebujesz metody klasowej lub statycznej. Nie dodawaj jednak dekoratora tylko po to, żeby ominąć brak self: najpierw ustal, czy operacja dotyczy stanu obiektu, całej klasy, czy nie potrzebuje żadnego z nich.

Traktuj klasę jak narzędzie, nie obowiązkowy etap

Prosty skrypt nie musi zaczynać się od hierarchii klas. Jeśli kilka funkcji stale przyjmuje te same dane i razem pilnują wspólnego stanu, model obiektowy może je uporządkować; przy krótkim przetwarzaniu pojedynczego słownika funkcja będzie zwykle prostsza.

Dobry test: jeśli potrafisz nazwać obiekt rzeczownikiem i wskazać, co może zrobić albo jak zmienia swój stan, klasa prawdopodobnie ma sens. Jeśli potrzebujesz tylko wygodnego pojemnika na stałe pola, rozważ @dataclass; gdy pola są nieprzewidywalne, zacznij od słownika.

FAQ - Najczęstsze pytania

Słownik sprawdzi się przy jednorazowych danych o zmiennym kształcie. @dataclass warto wybrać dla stałego zestawu pól, gdy obiekt głównie przechowuje dane. Zwykła klasa jest lepsza, gdy obiekt ma pilnować reguł albo wykonywać operacje na swoim stanie.

Przy wywołaniu job.finish() Python przekazuje obiekt job jako pierwszy argument metody, co można rozumieć jako Job.finish(job). Dzięki temu metoda może odczytywać i zmieniać stan właściwej instancji. self nie jest słowem kluczowym, ale warto używać tej standardowej nazwy dla czytelności.

Lista zapisana jako atrybut klasy, na przykład tags = [], może być wspólna dla wszystkich instancji tej klasy. Jeśli każdy obiekt ma mieć własną listę, utwórz ją w __init__ przez przypisanie self.tags = []. Ta sama zasada dotyczy innych zmiennych atrybutów, takich jak słowniki.

Moduł dataclasses może automatycznie wygenerować między innymi inicjalizację, porównywanie i tekstową reprezentację obiektu. Dzięki temu ogranicza powtarzalny kod przy klasach przechowujących dane. Sama adnotacja typu, na przykład name: str, nie zastępuje jednak walidacji danych.

Oceń artykuł

Ocena: 4.50 Liczba głosów: 2

Tagi

klasy
dataclass
słowniki
atrybuty
instancje
Autor Tymoteusz Maciejewski
Tymoteusz Maciejewski
Moje dni wypełnia zgłębianie kodu i analiza nowych technologii, zawsze z myślą o tym, jak najlepiej przekazać tę wiedzę dalej. Nazywam się Tymoteusz Maciejewski i od 12 lat aktywnie działam w świecie programowania, technologii i kariery w IT. Interesuje mnie nie tylko samo tworzenie oprogramowania, ale także proces, który prowadzi do zrozumienia złożonych zagadnień i uporządkowania ich w przystępny sposób. Na lukasz-zielinski.pl staram się dzielić się tym, co sam odkrywam, sprawdzając informacje u podstaw i dbając o to, by treści były aktualne i zrozumiałe dla każdego, kto chce rozwijać się w tej dynamicznej branży.

Udostępnij artykuł

Napisz komentarz