11.2 Konstruktori un atribūti
Stundas uzdevums: Iemācīties pareizi inicializēt objektus, izmantojot __init__ metodi un noklusējuma argumentus.
70 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~15 min) - pārraksti klasi ar __init__ · 2. uzdevums (~25 min) - pievieno noklusējuma vērtības · 3. uzdevums (~20 min) - pārbaudi datus konstruktorā. Papildu uzdevumu sāc tikai tad, ja pārējie trīs ir gatavi.
Pirms sāc: atver savu 11.1 stundas failu klases.py. Šoreiz atbrīvosies no atribūtu piešķiršanas ar roku.
Teorija: __init__ - objekta dzimšana
Manuāli iestatīt katra objekta atribūtus ir kļūdu pilna pieeja. __init__ ir konstruktors - speciāla metode, ko Python automātiski izsauc, kad veido jaunu objektu.
class Dalibnieks:
def __init__(self, vards, energija=100, klase="kapteinis"):
# self ir norāde uz JAUNO objektu
self.vards = vards
self.energija = energija
self.maks_energija = energija
self.klase = klase
self.aktiva = True
def info(self):
return f"{self.vards} ({self.klase}): {self.energija}/{self.maks_energija} enerģija"
# Izveide ar pozicionāliem argumentiem
v1 = Dalibnieks("Marta")
# Izveide ar nosauktiem argumentiem
v2 = Dalibnieks(vards="Jānis", energija=80, klase="prezentetajs")
print(v1.info()) # Marta (kapteinis): 100/100 enerģija
print(v2.info()) # Jānis (prezentetajs): 80/80 enerģija
Atribūtu tipi:
- Objekta atribūti (
self.x) - katram objektam savs. - Klases atribūti (definēti klases ķermenī ārpus metodēm) - kopīgi visiem objektiem.
- Privātie atribūti (sākas ar
_) - paredzēti tikai iekšējai lietošanai.
Praktiskie uzdevumi
1. uzdevums -
Pārraksti klasi ar __init__
Beigās objekta izveide un datu piešķiršana notiks vienā rindā.
- Ieraksti klasē
def __init__(self, vards, energija):. - Piešķir tajā
self.vards = vards. - Piešķir arī
self.energija = energija. - Izveido objektu ar
Dalibnieks("Anna", 100). - Izdrukā objekta vārdu un enerģiju.
- Mēģini izveidot objektu bez argumentiem un izlasi kļūdu.
Gatavs, kad: objektu var izveidot vienā rindā, bet bez argumentiem rodas TypeError.
2. uzdevums -
Pievieno noklusējuma vērtības
Beigās daļu argumentu varēs izlaist.
- Nomaini parametru uz
energija=100. - Pievieno trešo parametru
klase="kapteinis". - Izveido objektu tikai ar vārdu.
- Izdrukā visus trīs atribūtus.
- Izveido otru objektu, norādot arī klasi.
- Pievieno
self.maks_energija = energijaun paskaidro sev, kāpēc tas noder.
Gatavs, kad: objektu var izveidot gan ar vienu argumentu, gan ar trim, un abos gadījumos tas strādā.
3. uzdevums -
Pārbaudi datus konstruktorā
Beigās klase pati neļaus izveidot bezjēdzīgu objektu.
- Pievieno
if energija <= 0:un zem tāraise ValueError("Enerģijai jābūt pozitīvai"). - Pievieno pārbaudi arī tukšam vārdam.
- Mēģini izveidot objektu ar enerģiju
-5. - Izlasi kļūdas tekstu un pārbaudi, ka tas ir tavs.
- Mēģini izveidot objektu ar tukšu vārdu.
- Izveido derīgu objektu un pārliecinies, ka tas izdodas.
- Pieraksti vienu secinājumu: kāpēc pārbaudi labāk likt konstruktorā, nevis katrā metodē.
Gatavs, kad: nederīgi dati met tavu ValueError ar saprotamu tekstu, bet derīgs objekts izveidojas.
Papildu uzdevums - Pievieno izveides laiku
Ja pamatdarbs ir gatavs, liec objektam atcerēties, kad tas radīts.
- Importē
from datetime import datetime. - Pievieno konstruktorā
self.izveidots = datetime.now(). - Izveido divus objektus ar nelielu pauzi starp tiem.
- Izdrukā abu izveides laikus.
- Pieraksti, kāpēc šo vērtību nevajag padot kā argumentu.
Gatavs, kad: abiem objektiem ir atšķirīgs izveides laiks, ko tu nekur neievadīji.
Biežākās kļūdas
- Aizmirsts self konstruktora pirmajā argumentā:
__init__(self, ...)- vienmēr. - Maināmi klases atribūti:
klase_atrib = []tiek dalīts starp objektiem! - __init__ atgriež None: Nelieto
return self- tas nav pareizi.
Koda piemērs
class Dalibnieks:
def __init__(self, vards, energija=100, klase="kapteinis"):
if energija <= 0:
raise ValueError("Enerģijai jābūt pozitīvai")
if not vards:
raise ValueError("Vārds nedrīkst būt tukšs")
self.vards = vards
self.energija = energija
self.maks_energija = energija
self.klase = klase
v1 = Dalibnieks("Marta")
v2 = Dalibnieks(vards="Jānis", energija=80, klase="prezentetajs")
print(f"{v1.vards}: {v1.energija}/{v1.maks_energija}")
print(f"{v2.vards} ({v2.klase}): {v2.energija}/{v2.maks_energija}")
Jānis (prezentetajs): 80/80