🏗️ Objektorientētā programmēšana
OOP ļauj modelēt reālo pasauli ar objektiem – kastēm, kurās glabājas dati (atribūti) un uzvedība (metodes). Python OOP pamati: klases, mantojamība un speciālās metodes.
Klases un objekti
Teksts
# Klases definēšana
class Autos:
# Klases atribūts (kopīgs visiem objektiem)
kategōrija = "Transportlīdzeklis"
# __init__ – konstruktors (izsauc, veidojot objektu)
def __init__(self, marka, modelis, gads):
# Objekta atribūti (katram objektam savi)
self.marka = marka
self.modelis = modelis
self.gads = gads
self._ātrums = 0 # Konvencija: _ = "privāts"
# Metode
def apraksts(self):
return f"{self.gads}. g. {self.marka} {self.modelis}"
def paātrināt(self, daudzums):
self._ātrums += daudzums
print(f"Ātrums: {self._ātrums} km/h")
def bremzēt(self):
self._ātrums = max(0, self._ātrums - 10)
# Objektu izveide
audi = Autos("Audi", "A4", 2022)
bmw = Autos("BMW", "X5", 2023)
print(audi.apraksts()) # 2022. g. Audi A4
print(bmw.marka) # BMW
audi.paātrināt(50) # Ātrums: 50 km/h
audi.paātrināt(30) # Ātrums: 80 km/h
# Klases atribūts pieejams caur klasi vai objektu
print(Autos.kategōrija) # Transportlīdzeklis
print(audi.kategōrija) # Transportlīdzeklis
Mantojamība
Teksts
# Bāzes klase
class Dzīvnieks:
def __init__(self, vārds, suga):
self.vārds = vārds
self.suga = suga
def runāt(self):
print(f"{self.vārds} runā")
def __str__(self):
return f"{self.suga}: {self.vārds}"
# Apakšklase
class Suns(Dzīvnieks):
def __init__(self, vārds, šķirne):
super().__init__(vārds, "Suns") # Izsauc vecāku __init__
self.šķirne = šķirne
def runāt(self): # Override
print(f"{self.vārds} rej: Vau!")
def nest(self, priekšmets):
print(f"{self.vārds} nes {priekšmets}")
class Kaķis(Dzīvnieks):
def runāt(self):
print(f"{self.vārds} saka: Māu!")
# Izmantošana
suns = Suns("Reks", "Labradoru retrivers")
kaķis = Kaķis("Minca", "Persiešu kaķis")
suns.runāt() # Reks rej: Vau!
kaķis.runāt() # Minca saka: Māu!
suns.nest("bumbu") # Reks nes bumbu
print(suns) # Suns: Reks
print(isinstance(suns, Suns)) # True
print(isinstance(suns, Dzīvnieks)) # True – mantojamība!
print(issubclass(Suns, Dzīvnieks)) # True
@property, @classmethod, @staticmethod
Teksts
class Temparatūra:
def __init__(self, celsius=0):
self._celsius = celsius # Privāts atribūts
# @property – piekļuve kā atribūtam, bet ar loģiku
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, vērtība):
if vērtība < -273.15:
raise ValueError("Temp nevar būt zemāka par absolūto nulli!")
self._celsius = vērtība
@property
def fahrenheit(self):
return self._celsius * 9/5 + 32
# @classmethod – alternatīvi konstruktori
@classmethod
def no_fahrenheit(cls, fahrenheit):
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
# @staticmethod – utilīta, nav piesaistīta objektam
@staticmethod
def ir_auksts(celsius):
return celsius < 10
# @property izmantošana
t = Temparatūra(25)
print(t.celsius) # 25
print(t.fahrenheit) # 77.0
t.celsius = 100
print(t.fahrenheit) # 212.0
# t.celsius = -300 # ValueError!
# @classmethod
t_no_f = Temparatūra.no_fahrenheit(212)
print(t_no_f.celsius) # 100.0
# @staticmethod
print(Temparatūra.ir_auksts(5)) # True
print(Temparatūra.ir_auksts(20)) # False
Speciālās metodes (Dunders)
Metodes ar dubultsīkstiniem __ ļauj objektiem "saprast" Python operatorus.
💡 Dataclasses – ātrāks veids
Python 3.7+ piedāvā @dataclass dekoratoru, kas automātiski ģenerē __init__, __repr__, __eq__.
Teksts
class Vektors:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"Vektors({self.x}, {self.y})"
def __repr__(self):
return f"Vektors(x={self.x}, y={self.y})"
def __len__(self):
return 2 # 2-dimensiju vektors
def __add__(self, cits):
return Vektors(self.x + cits.x, self.y + cits.y)
def __sub__(self, cits):
return Vektors(self.x - cits.x, self.y - cits.y)
def __mul__(self, skalārs):
return Vektors(self.x * skalārs, self.y * skalārs)
def __eq__(self, cits):
return self.x == cits.x and self.y == cits.y
def __abs__(self):
return (self.x**2 + self.y**2) ** 0.5
v1 = Vektors(1, 2)
v2 = Vektors(3, 4)
print(v1) # Vektors(1, 2)
print(repr(v1)) # Vektors(x=1, y=2)
print(len(v1)) # 2
print(v1 + v2) # Vektors(4, 6)
print(v1 * 3) # Vektors(3, 6)
print(abs(v2)) # 5.0
print(v1 == Vektors(1, 2)) # True
# Biežāk lietotie dunders:
# __init__ – konstruktors
# __str__ – cilvēkam lasāms teksts
# __repr__ – izstrādātājam paredzēts
# __len__ – len()
# __getitem__ – obj[indekss]
# __contains__ – in operators
# __iter__ – for cilpā
# __enter__/__exit__ – with blokā
from dataclasses import dataclass, field
@dataclass
class Persona:
vārds: str
vecums: int
hobiji: list = field(default_factory=list)
def prezentēt(self):
return f"{self.vārds} ({self.vecums} g.)"
p = Persona("Anna", 25, ["lasīšana", "peldēšana"])
p2 = Persona("Anna", 25, ["lasīšana", "peldēšana"])
print(p) # Persona(vārds="Anna", vecums=25, hobiji=["lasīšana", "peldēšana"])
print(p.prezentēt()) # Anna (25 g.)
print(p == p2) # True – automātiski salīdzina laukus