220 likes | 416 Views
Python - objekti, razredi . Od kje in zakaj. Moj prvi razred. Razredi za uporabo znotraj nekega programa "lokalni" razredi Kot prej class MojRazred : def __init__(self, sporočilo ) : self.vsebina = sporočilo def izpiši (self) : print( self.vsebina )
E N D
Python - objekti, razredi ... Od kje in zakaj
Moj prvi razred • Razredi za uporabo znotraj nekega programa • "lokalni" razredi • Kot prej class MojRazred : def __init__(self, sporočilo) : self.vsebina = sporočilo def izpiši(self) : print(self.vsebina) # s tem smodefiniralinovrazredMojrazred # uporaba objektMojR = MojRazred("Objektnoprogramiranjen v vsakoslovensko vas!") objektMojR.izpiši()
"Knjižnice razredov" class MojRazred : def __init__(self, sporočilo) : self.vsebina = sporočilo def izpiši(self) : print(self.vsebina) • Datoteka knjiznicaRaz.py
In uporaba importknjiznicaRaz objektMojR = knjiznicaRaz.MojRazred("Objektno " + "programiranje v vsako slovensko vas!") objektMojR.izpiši()
Seveda je v knjižnici lahko več razredov class Ulomek : def __init__(self, st, im) : self.stevec = st self.imenovalec = im def __add__(self, ulP) : novŠtevec = self.stevec + ulP.stevec novImenovalec = self.imenovalec + ulP.imenovalec return Ulomek(novŠtevec, novImenovalec) def izpis(self) : print(str(self.stevec) + " / " + str(self.imenovalec), end='') # ===================================== classMojRazred : def __init__(self, sporočilo) : self.vsebina = sporočilo def izpiši(self) : print(self.vsebina)
In uporabljamo lahko le tiste, ki jih potrebujemo import knjiznicaRaz # vnospodatkov beri = input("Števeculomka: ") stevec = int(beri) beri = input("Imenovaleculomka: ") imenovalec = int(beri) mojUl = knjiznicaRaz.Ulomek(stevec, imenovalec) # izpis print("Ulomek je: ", end='') mojUl.izpis() print() # "delo" polovica = knjiznicaRaz.Ulomek(1, 2) mojUl = mojUl + polovica # izpis print("Spremenjeniulomek je: ", end='') mojUl.izpis() print() 6
Združevanje podatkov • Denimo, da pišemo program, ki bo pomagal upravljati farmo zajcev • Za vsakega zajca poznamo: • serijsko številko • spol • težo • Kako doseči, da se podatki “držijo” skupaj • Sestavimo razred Zajec • Opis podatkov, ki sestavljajo poljubnega zajca
Razred Zajec class Zajec : def __init__(self) : self.serijska = 'Je še ni' self.spol = True self.masa = 1 • S tem imamo napisan opis, kako je določen poljuben zajec • Načrt, kakšni so zajci • Ni to konkreten zajec • Ni namenjeno poganjanju kot program
Uporaba razreda Zajec • Program, kjer delamo z zajci: • importMojiRazredi # "ena druga knjižnica" • Če v programu potrebujemo konkretnega zajca, ga “ustvarimo” z • MojiRazredi.Zajec() • Ustvaril se je konkreten zajec po navodilih za razred Zajec (ta zajec ima torej tri podatke / lastnosti / komponente) • Metoda je vrnila naslov, kje ta konkretni zajec je • rjavko = MojiRazredi.Zajec() • V spremenljivki rjavko je naslov, kje je novo ustvarjeni zajec (objekt)
Dostop do podatkov v objektu • rjavko.spol = True • rjavko.serijska = 'BRGH_17_A' • rjavko.masa = 3.2 z1 = MojRazred.Zajec() z1.serijska = '1238-12-0' z1.spol = False z1.masa = 0.12 z1.masa = z1.masa + 0.3 print('Zajec ima ser. št.:' + z1.serijska)
Razred – shramba podatkov class Ulomek : def__init__(self) : # privzete vrednosti self.stevec = 1self.imenovalec = 2 • Kaj sedaj? • Uporabljamo v drugih programih (razredih) • x = MojaKnjižnica.Ulomek() • Kako “napolniti” stevec in imenovalec? • x.stevecinx.imenovalecsta običajni spremenljivki! • x.stevec = 1 • x.imenovalec = x.stevec + 1
Povzetek • Definicija razreda • Običajno v knjižnici! class ImeRazreda: def__init__(self) : # začetno stanje self.lastnost1 = <začetnaVrednost> self.lastnost2 = <začetnaVrednost> ... self.lastnostn = <začetnaVrednost>
Povzetek • Uporaba razreda • Če potrebujemo primerek razreda • ImeKnj.ImeRazreda() • Ustvari prostor in pove, kje ta prostor je • Naslov prostora shranimo v neko spremenljivko (tipa ImeRazreda), denimo mojaSpTipaImeRazreda • Dostop do prostorov za hranjenje • Operator . • imeObjekta.elementi • imeObjekta.imeLastnosti • mojaSpTipaImeRazreda.starost
Konstruktor • __ init __ • Ob tvorbi objekta nastavimo začetno stanje spremenljivk • in morda opravimo še kaj – o tem kasneje • Tej funkciji (metodi) rečemo konstruktor • Izvede se ko ustvarimo primerek razreda • ImeKnj.ImeRazreda()
Razred Zajec class Zajec : def __init__(self) : self.serijska = 'Je še ni' self.spol = True self.masa = 1 • Zajca “ustvarimo” z ImeKnj.Zajec() • Ustvaril se je konkreten zajec po navodilih iz konstruktorja Zajec() (ta zajec ima torej tri podatke z vrednostmi, kot je predpisano v konstruktorju) • Kaj je self?
self • self • Pomeni objekt, ki ga "obdelujemo" • V konstruktorju – objekt, ki ga ustvarjamo • self.spol • Lastnost/komponenta spol objekta, ki se ustvarja • rjavko = ImeKnj.Zajec() • belko = ImeKnj.Zajec() • Pri prvem klicu se je v konstruktorju self nanašal na rjavko, pri drugem na belko.
self v ostalih metodah • Kasneje – pisali bomo metode, ki se bodo uporabljale nad razredi • Kako se v metodah razreda sklicati na ta objekt (objekt, nad katerim je izvajana metoda)? • Razred MojRazred in v njem komponenta starost. Napišimo metodo MetodaNeka(), ki izpiše starost objekta, nad katerim izvajamo metodo. • Klici bodo npr.: objA.MetodaNeka(), objC.MetodaNeka() • Kako v postopku za MetodaNeka povedati, da gre • Prvič za objekt z imenom objA • drugič za objekt z imenom objC
self v ostalih metodah • Kako povedati, da naj se ob klicu objA.MetodaNeka() uporabi starost objekta objA, ob klicu objC.MetodaNeka() pa starost objekta objC? • print("Starost je: " + str(??.starost)) • Ob prvem klicu je ??objA, ob drugem paobjC. To "zamenjavo" dosežemo z self. V metodi MetodaNeka kot prvi parameter napišemo self in v telesu metode • print("Starost je: " + self.starost) • Ob prvem klicuselfpomeniobjA, ob drugem paobjC.
Metode / funkcije • Metode so funkcije, ki so "pridružene" objektom • Klic: • imeObjekta.imeMetode(... parametri ...) • Klic funkcije • imeFunkcije(... Parametri ...) • Za klicanje metode potrebujemo objekt ustreznega tipa • Metode so definirane v razredih • Prvi parameter metod je self • Lahko bi napisali tudi jaz (ali kaj drugega) • A "dogovor" je, da tega ne počnemo • Zmedeni drugi uporabniki
Več konstruktorjev • Uporabniki bi poleg privzetega zajca, radi še možnost, da bi takoj, ko zajca naredijo, temu določili še serijsko številko. Radi bi torej konstruktor • Zajec(serijskaSt) • Včasih pa so zajci "nestandardni“ • Zajec(serijskaSt, spol, teza) • Potrebujemo več načinov nastavljanja začetnega stanja objekta • Več konstruktorjev: • Več metod z enakim imenom • Je to možno?
Načeloma to v Pythonu ne gre • Lahko pa uporabljamo parametre s privzetimi vrednostmi • Isto tehniko lahko uporabimo tudi pri funkcijah in ostalih metodah • def nekaj(x, y = 7, z = 12) : ... • Funkcijo lahko kličemo: • nekaj(3) • x dobi vrednost 3, y 7 in z 12 • nekaj(3, 5) • x dobi vrednost 3, y 5 in z 12 • nekaj(3, 5, 9) • x dobi vrednost 3, y 5 in z 9 • Lahko pa tudi • nekaj(x = 3) • x dobi vrednost 3, y 7 in z 12 • nekaj(3, Z = 5) • x dobi vrednost 3, y 7 in z 5 • nekaj(y = 3, x = 5, z = 9) • x dobi vrednost 5, y 3 in z 9 • Ali pa še malo bolj "čaramo" (raje ne ;-) )
Konstruktorji razreda Zajec class Zajec : def __init__(self, serijska='Je še ni', samec = True, teža = 1) : self.serijska = serijska self.spol = samec self.masa = teža Enkrat serijska pomeni lastnost, drugič je parameter metode!