Wyjaśnienie lekcji
Po tej lekcji będziesz potrafić:
__init__.Atrybut instancji jest przechowywany w jednym obiekcie, zwykle przypisywany w __init__ jako self.name = name. Atrybut klasy jest zapisany w ciele klasy i współdzielony jako wartość domyślna przez każdą instancję tej klasy:
class Worker:
region = "eu"
def __init__(self, name):
self.name = nameWorker.region odczytuje ustawienie klasy. worker.region także je odczytuje, dopóki ten konkretny obiekt nie ma własnego atrybutu region. Jeśli przypiszesz worker.region = "us", ten obiekt przesłania ustawienie klasy; nie aktualizuje to pozostałych workerów.
Dla naprawdę wspólnej konfiguracji aktualizuj Worker.region (klasę), a nie pojedynczą instancję. Dla stanu przypadającego na obiekt, takiego jak nazwa workera, liczba ponowień lub historia zdarzeń, używaj self.attribute w __init__.
Ważna pułapka modyfikowalnego stanu: lista zdefiniowana w ciele klasy może być współdzielona przez wszystkie instancje. Jeśli każda instancja potrzebuje własnej listy, utwórz self.events = [] w konstruktorze.
class ApiClient:
scheme = "https"
def __init__(self, service):
self.service = service
first = ApiClient("users")
second = ApiClient("billing")
print(f"{first.service}: {first.scheme}")
print(f"{second.service}: {second.scheme}")Wynik:
users: https
billing: httpsOba obiekty odczytują to samo ustawienie klasy, zachowując własne nazwy usług.
class Job:
mode = "safe"
first = Job()
second = Job()
Job.mode = "fast"
print(first.mode)
print(second.mode)Wynik:
fast
fastŻadna instancja nie definiuje własnego mode, więc obie nadal odczytują atrybut klasy.
class Storage:
tier = "standard"
primary = Storage()
backup = Storage()
primary.tier = "premium"
print(primary.tier)
print(backup.tier)
print(Storage.tier)Wynik:
premium
standard
standardprimary.tier stało się atrybutem instancji; wspólna wartość domyślna klasy pozostała bez zmian.
class Monitor:
def __init__(self, name):
self.name = name
self.events = []
def record(self, event):
self.events.append(event)
api = Monitor("api")
queue = Monitor("queue")
api.record("started")
print(api.events)
print(queue.events)Wynik:
['started']
[]Każde wywołanie konstruktora tworzy nową listę dla jednego monitora.
| Sytuacja | Gdzie przypisać |
|---|---|
| Wspólna wartość domyślna lub ustawienie | W ciele klasy: mode = "safe" |
| Zmiana wspólnego ustawienia | Worker.mode = "fast" |
| Stan przypadający na obiekt | W __init__: self.name = name |
| Nadpisanie wspólnej wartości domyślnej dla jednej instancji | worker.mode = "custom" |
| Modyfikowalna lista przypadająca na obiekt | W __init__: self.events = [] |
obj.setting = value nie zmienia ClassName.setting; tworzy lub aktualizuje atrybut instancji.self.name w ciele klasy nie jest sposobem inicjalizacji instancji; użyj __init__.