89 lines
3 KiB
Markdown
89 lines
3 KiB
Markdown
# Kapitel 02: Der Konstruktor `__init__` und das geheimnisvolle `self` 💳
|
|
|
|
Im ersten Kapitel haben wir Attribute noch manuell nach dem Erstellen zugewiesen:
|
|
```python
|
|
bello = Haustier()
|
|
bello.name = "Bello"
|
|
bello.alter = 3
|
|
```
|
|
Das ist mühsam und fehleranfällig: Was passiert, wenn man vergisst, `.alter` zu setzen? Richtig: Das Programm stürzt ab, sobald jemand darauf zugreift!
|
|
|
|
Deshalb gibt es in Python den **Konstruktor**: `__init__`.
|
|
|
|
---
|
|
|
|
## 🛠️ Was ist `__init__`?
|
|
|
|
`__init__` steht für *initialisieren* (vorbereiten/startklar machen).
|
|
|
|
Es ist eine **spezielle Methode**, die Python **automatisch aufruft**, sobald du ein neues Objekt erstellst.
|
|
|
|
---
|
|
|
|
## 📱 Vollständiges Praxisbeispiel: Die Smartphone-Klasse
|
|
|
|
```python
|
|
class Smartphone:
|
|
# Der Konstruktor wird automatisch beim Erstellen aufgerufen:
|
|
def __init__(self, modell, speicher_gb, akku=100):
|
|
self.modell = modell # z.B. "iPhone 15"
|
|
self.speicher_gb = speicher_gb # z.B. 128
|
|
self.akku = akku # Standardwert ist 100%
|
|
|
|
def benutzen(self, minuten):
|
|
verbrauch = minuten * 0.5
|
|
if self.akku >= verbrauch:
|
|
self.akku -= verbrauch
|
|
return f"{self.modell}: {minuten} Min. genutzt. Akku: {self.akku:.0f}%"
|
|
else:
|
|
self.akku = 0
|
|
return f"{self.modell}: Akku ist leer!"
|
|
|
|
def aufladen(self):
|
|
self.akku = 100
|
|
return f"{self.modell} ist wieder voll aufgeladen (100%)!"
|
|
|
|
# Verwendung:
|
|
mein_handy = Smartphone("iPhone 15", 256)
|
|
altes_handy = Smartphone("Galaxy S10", 64, akku=40)
|
|
|
|
print(mein_handy.benutzen(30)) # Verbraucht 15% -> 85% Rest
|
|
print(altes_handy.benutzen(90)) # Akku wird leer!
|
|
print(altes_handy.aufladen()) # Wieder 100%
|
|
```
|
|
|
|
---
|
|
|
|
## 🪞 Was bedeutet eigentlich `self`?
|
|
|
|
- `self` bedeutet auf Deutsch **"ich selbst"** oder **"dieses konkrete Objekt hier"**.
|
|
- Wenn du `mein_handy.benutzen(30)` aufrufst, übergibt Python das neu entstandene `mein_handy`-Objekt automatisch als erstes Argument `self`.
|
|
- `self.akku -= verbrauch` zieht den Strom genau vom Akku dieses einen Handys ab.
|
|
|
|
---
|
|
|
|
## ⚠️ Typische Fehler vermeiden
|
|
|
|
1. **`__init__` mit zwei Unterstrichen schreiben:**
|
|
- ❌ `def _init_(self):` (wird nicht aufgerufen!)
|
|
- ✅ `def __init__(self):` (korrekt!)
|
|
2. **`self` bei jeder Methode als ersten Parameter:**
|
|
- ❌ `def einzahlen(betrag):` -> führt zu `TypeError: einzahlen() takes 1 positional argument but 2 were given`
|
|
- ✅ `def einzahlen(self, betrag):`
|
|
3. **Zuweisungsrichtung beachten:**
|
|
- ❌ `inhaber = self.inhaber` (falsch herum!)
|
|
- ✅ `self.inhaber = inhaber` (speichert den Parameter im Attribut)
|
|
|
|
---
|
|
|
|
## 🎯 Deine Aufgabe: Das Bankkonto
|
|
|
|
Öffne `aufgabe.py`. Du programmierst eine Klasse `Bankkonto`:
|
|
1. Schreibe den Konstruktor `__init__`.
|
|
2. Ergänze Methoden zum Einzahlen (`einzahlen`) und Auszahlen (`auszahlen`), die darauf achten, dass man nicht ins Minus rutscht.
|
|
3. Ergänze eine Methode `info_text()`.
|
|
|
|
### Testen:
|
|
```bash
|
|
python3 test_aufgabe.py
|
|
```
|