Kap 3.4
Inkapsling och attribut
Objekt ska själva få styra hur deras data får ändras.
Mål
Efter lektionen ska du kunna...
- förklara vad inkapsling innebär
- känna igen publika och interna attribut
- använda metoder för att läsa och ändra data
- förklara getter och setter
Problem
Attribut kan ändras direkt
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
Här är både owner och balance publika attribut.
Det betyder att annan kod kan läsa och ändra dem direkt.
Problemet är störst för balance, eftersom saldot behöver regler.
Problem
Orimliga värden kan sparas
account = BankAccount("Emma", 1000)
account.balance = -999
print(account.balance)
-999
Objektet fick ingen chans att stoppa ändringen.
Inkapsling
Skydda objektets data
Inkapsling betyder att objektets inre data inte ändras hur som helst.
Annan kod ska gå via metoder.
Metoderna kan kontrollera om ändringen är tillåten.
Attribut
Publikt och internt
self.owner = owner
self._balance = balance
ownerär publikt._balanceär markerat som internt.- Understrecket betyder: använd inte detta direkt utifrån.
Viktigt
Python stoppar inte allt
_balance är inte låst.
Det går fortfarande att skriva account._balance = -999.
Understrecket är en konvention, alltså en överenskommelse mellan programmerare.
Det betyder: använd helst metoderna i stället för att ändra detta direkt.
Klass
Bankkonto med internt saldo
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self._balance = balance
Saldot ska hanteras via metoder.
Getter
Läs värdet via metod
def get_balance(self):
return self._balance
En getter hämtar eller returnerar ett värde.
Här kan annan kod läsa saldot utan att ändra det.
Ändra
Sätt in pengar kontrollerat
def deposit(self, amount):
if amount > 0:
self._balance += amount
Metoden tillåter bara positiva belopp.
Objektets saldo ändras bara om villkoret stämmer.
Ändra
Ta ut pengar kontrollerat
def withdraw(self, amount):
if 0 < amount <= self._balance:
self._balance -= amount
else:
print("Uttaget nekas.")
Kontot får inte övertrasseras.
Stegvis
Saldot ändras med metoder
account = BankAccount("Emma", 1000)
print(account.get_balance())
account.deposit(500)
print(account.get_balance())
account.withdraw(200)
print(account.get_balance())
1000
1500
1300
Setter
Setter ändrar efter kontroll
def set_grade(self, grade):
if 0 <= grade <= 100:
self._grade = grade
else:
print("Betyget måste vara mellan 0 och 100.")
En setter används när ett nytt värde ska kontrolleras innan det sparas.
Jämförelse
Direkt ändring eller metod?
account.balance = -999
Direkt ändring: ingen kontroll.
account.withdraw(200)
Metod: objektet kan kontrollera ändringen.
Hela klassen
BankAccount
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self._balance = balance
def deposit(self, amount):
if amount > 0:
self._balance += amount
def withdraw(self, amount):
if 0 < amount <= self._balance:
self._balance -= amount
else:
print("Uttaget nekas.")
def get_balance(self):
return self._balance
Öva
Skapa Student
- Skapa klassen
Student. - Låt
namevara publikt. - Låt
_gradevara internt. - Skriv
set_grade()med kontroll 0-100. - Skriv
get_grade().
Sammanfattning
Kom ihåg
- Inkapsling skyddar objektets data.
_attributmarkerar intern data i Python.- Getters läser värden.
- Setters ändrar värden efter kontroll.
- Objekt bör styra hur deras attribut får ändras.