Objekt je skupek podatkov in metod (funkcij), s katerimi dostopamo do podatkov. Primeri:
ulomek predstavimo kot objekt, ki hrani dva podatka, stevec in imenovalec in ima metode za delo z ulomki (okrajšaj, aritmetične operacije).
točkasto telo predstavimo kot objekt, ki hrani podatke o masi, poziciji in hitrosti in ima metode kot so gibalna_kolcina, kineticna_energija, deluj(sila, čas) itd.
oseba predstavimo kot objekt, ki hrani podatke o osebi (ime, priimek, datum rojstva, naslov, …) in metode (trenutna_starost, polno_ime, …)
Skratka, z objekti podatke organiziramo v smiselne uporabne enote.
Objekt torej v sebi hrani podatke, ki jim pravimo tudi atribitute (attribute), včasih pa tudi polja (fields) ali komponente (components). Na primer, objekt, ki predstavlja točkasto telo, bi lahko imel atribute masa, x, y, vx in vy.
Do atributa a v objektu o dostopamo z o.a.
Metodo m na objektu o pokličemo z o.m(...).
Običajno imamo več objektov iste vrste, na primer za vsako točkasto telo v simulaciji en objekt. V ta namen definiramo razred, ki so opisuje objekte iste vrste. Vsaj objekt torej pripada nekemu razredu.
V Pythonu definiramo razred takole:
class ImeRazreda():
"""Dokumentacija o razredu"""
def __init__(self, ....):
"""Posebna metoda (konstruktor), ki se pokliče, ko se ustvari nov objekt."""
...
def __repr__(self):
"""Metoda, ki pretvori objekt v niz, ki ga predstavlja."""
....
def __str__(self):
"""Metoda, ki pretvori objekt v uporabniku prijazen niz."""
....
# Ostale metode
def metoda1(self, ....):
"Moja prva metoda"
....
def metoda2(self, ....):
"Moja druga metoda"
....
...
Nov objekt razreda MojRazred naredimo z izrazom MojRazred(....). Naredi se nov objekt in na njem se pokliče metoda __init__(self, ...) (pravimo ji konstruktor), pri čemer je self novonastali objekt.
Objektna metoda vedno sprejme prvi argument self, to je objekt, na katerem se izvaja.
Poznamo tudi statične metode. Te ne delujejo na objektih, ampak so samo definirane znotraj razreda. Za primer glej metodo gcd v ulomek.py..
Oglejmo si primera ulomek.py in delec.py.
Včasih potrebujemo zelo preproste objekte, ki v atributih hranijo podatke, nimajo po definiranih nobenih metod. Seveda lahko v ta namen definiramo razred. Vendar pa knjižnica collections ponuja tudi elegantno rešitev imenovane nabore (named tuples). Več o tem najdete v dokumentaciji o namedtuple in v primeru ocene.py.
Iteratorji so posebni objekti, ki jih uporabljamo za pregledovanje tabel, datotek, in ostalih zbirk podatkov. Kot predpisuje dokumenatacija za iterator, je to objekt ki ima:
__next__(self), ki vrne naslednji element, ali sproži izjemo StopIteration, če naslednjega elementa ni.__iter__(self), ki vrne self.Mnogi objekti niso iteratorji (tabela, nabor, slovar, niz, datoteka, …), ampak lahko vrnejo iterator, ki našteje elemente, ki jih vsebujejo, glej dokumentacijo za iterable. Tak mora imeti metodo __iterable__, ki vrne iterator. Pravimo, da je objekt iterabilen.
Če imamo iterabilen objekt o, lahko pregledamo njegove elemente z zanko for. Koda
for x in o:
...
je ekvivalentna kodi:
it = iter(o)
while True:
try:
x = next(it)
...
except StopIteration:
break
Nekatere najbolj uporabne iteratorje najdete v knjižnici itertools.
Generator je posebna funkcija, ki namesto return uporablja yield. To v resnici ni funkcija, ampak poseben mehanizem v Pythonu, s katerim elegantno naredimo iterator. Če je g generator, ob klicu g(...) dobimo pripadajoči iterator, ki vrača elemente, ki jih generira g z ukazom yield. Takole bi naredili range kot generator, če ga še ne bi imeli:
def mojRange(a, b):
"""Generator, ki generira vsa cela števila med a in b."""
while a < b:
yield a
a = a + 1