Erklärung zur Lektion
Nach dieser Lektion kannst du:
__init__ erstellst.Ein Instanzattribut wird an einem Objekt gespeichert und meist in __init__ als self.name = name zugewiesen. Ein Klassenattribut wird im Klassenkörper geschrieben und von jeder Instanz dieser Klasse als Standardwert gemeinsam genutzt:
class Worker:
region = "eu"
def __init__(self, name):
self.name = nameWorker.region liest die Klasseneinstellung. worker.region liest sie ebenfalls, bis dieses bestimmte Objekt ein eigenes Attribut region hat. Wenn du worker.region = "us" zuweist, überdeckt dieses Objekt die Klasseneinstellung; die anderen Worker werden dadurch nicht aktualisiert.
Für wirklich gemeinsame Konfiguration aktualisierst du Worker.region (die Klasse), nicht eine einzelne Instanz. Für Zustand pro Objekt, etwa den Namen eines Workers, Wiederholungsversuche oder den Ereignisverlauf, verwende self.attribute in __init__.
Wichtige Falle bei veränderlichem Zustand: Eine im Klassenkörper definierte Liste kann von allen Instanzen gemeinsam genutzt werden. Wenn jede Instanz ihre eigene Liste braucht, erstelle self.events = [] im Konstruktor.
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}")Ausgabe:
users: https
billing: httpsBeide Objekte lesen dieselbe Klasseneinstellung und behalten ihre eigenen Dienstnamen.
class Job:
mode = "safe"
first = Job()
second = Job()
Job.mode = "fast"
print(first.mode)
print(second.mode)Ausgabe:
fast
fastKeine Instanz definiert ein eigenes mode, also lesen beide weiterhin das Klassenattribut.
class Storage:
tier = "standard"
primary = Storage()
backup = Storage()
primary.tier = "premium"
print(primary.tier)
print(backup.tier)
print(Storage.tier)Ausgabe:
premium
standard
standardprimary.tier wurde zu einem Instanzattribut; der gemeinsame Klassenstandard blieb unverändert.
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)Ausgabe:
['started']
[]Jeder Konstruktoraufruf erstellt eine neue Liste für genau einen Monitor.
| Situation | Wo zuweisen |
|---|---|
| Gemeinsamer Standardwert oder gemeinsame Einstellung | Im Klassenkörper: mode = "safe" |
| Gemeinsame Einstellung ändern | Worker.mode = "fast" |
| Zustand pro Objekt | In __init__: self.name = name |
| Einen gemeinsamen Standardwert für eine Instanz überschreiben | worker.mode = "custom" |
| Veränderliche Liste pro Objekt | In __init__: self.events = [] |
obj.setting = value ändert ClassName.setting nicht; es erstellt oder aktualisiert ein Instanzattribut.self.name im Klassenkörper zuzuweisen ist nicht die Art, wie Instanzen initialisiert werden; verwende __init__.