Objekter i Python
Klasser og objekter
Python er et objektorientert språk. Vi kan betrakte datatyper og innebygde datastrukturer som objekter.
Nedenfor skal vi se på noen svært enkle eksempler på egne klasser. Innføringen er basert på noen enkle eksempler.
Eksempel 1
I det første eksempelet lager vi en klasse for å beskrive personobjekter, og vi lager en person. Vi lager personklassen som en klasse som arver fra object. objekt er "alle klassers mor" i det nye klassebegrepet i Python. object har, i Python som i andre språk med tilsvarende konstruksjon, noen grunnleggende metoder som er nyttig i en del sammenhenger. Vi forfølger ikke dette i det første eksempelet.
class person(object): def __init__(self,n,a): self.name=n self.address=a ole=person('ole','Halden') print (ole.name)
Merk at __init__ fungerer som en konstruktor. Merk videre bruken av self. Siden Python ikke har noen mekanismer for å deklarere variable, brukes f.eks. self.address for å definere en lokal variabel address, "dette objektets address". self må alltid være i den formelle parameterlista i klassemetoder. Vi kan skrive om personklassen slik at den ligner på den formen vi vanligvis bruker i f.eks. Java.
class person(object): def __init__(self,n,a): self.name=n self.address=a def getName(self): return self.name def getAddress(self): return self.address def setName(self,n): self.name=n def setAddress(self,a): self.address=a def __str__(self): return self.name+' fra '+self.address ole=person('ole','Halden') print (ole.__str__()) print (ole.getName()) ole.setName('Ole Jakob') print (ole.__str__()) print (ole.getName())
med resultat:
ole fra Halden ole Ole Jakob fra Halden Ole Jakob
Merk at __str__(self) er en redefinisjon av tilsvarende funksjon i object.
Eksempel 2
Nå bygger vi ut personklassen, og definerer en subklasse: ansatt'.
class person(object): def __init__(self,n,a): self.name=n self.address=a def getName(self): return self.name def getAddress(self): return self.address def setName(self,n): self.name=n def setAddress(self,a): self.address=a def __str__(self): return self.name+' fra '+self.address class ansatt(person): def __init__(self,n,a,j): person.__init__(self,n,a) self.job=j def getJob(self): return self.job def setJob(self,j): self.job=j def __str__(self): return person.__str__(self)+' har jobb som '+self.job hans=ansatt('hans','Halden','vaktmester') print (hans.__str__()) hans.setName('Hans Jakob') hans.setJob('regnskapssjef') print (hans.__str__()) print (super(ansatt,hans).__str__())
med utskriften:
hans fra Halden har jobb som vaktmester Hans Jakob fra Halden har jobb som regnskapssjef Hans Jakob fra Halden
Eksempel 3
Et litt mer praktisk eksempel: Vi leser data fra en kommaseparert fil og bygger opp en liste av objekter, ett for hver linje. Som datagrunnlag bruker vi landbeskrivelser fra geonames [1] . Datasettet er beskrevet i website: Data , og dataene er slik: https://borres.hiof.no/wep/data/geografi/land.txt
from urllib import request """ Using a class to administrate geodata """ #--------------------------------- # a class to hold : countryname,continent,area, capital class country(object): def __init__(self,plist): self.countryName=plist[4] self.continent=plist[8] self.capital=plist[5] if plist[6]=='': self.area=0.0 else: self.area=float(plist[6]) def __str__(self): return self.countryName def printAllOfMe(self): return str(self.area)+'\t'+self.countryName+' - '+self.capital #------------------------------- # continets [isocode,fullname] continents=[['EU','Europa'],['AS','Asia'],['NA', 'North America'], ['AN','Antarctica'],['SA','South America'],['OC','Oceania'], ['','No region']] # --------------------------------- # read from whereever you place the data # pick a country from each line and produce an object list def makeCountryList(): try: allCountries=[] # quick and dirty: surl='https://borres.hiof.no/wep/data/geografi/land.txt' f=request.urlopen(surl) T=f.read().decode() #since read returns bytes f.close() lines=T.split('\n') for line in lines: parts=line.split('\t') if len(parts)!=12 or line.startswith('iso'): continue allCountries.append(country(parts)) return allCountries except: print('error') return[] #------------------- # report a list pr continent def reportContinent(countryList): result='' for c in continents: result+=c[1]+'\n' for cobj in countryList: if cobj.continent==c[0]: result+='\t'+cobj.__str__()+'\n' return result #------------------ # report all countries sorted on area # sort helper def sortKey(c): return c.area def reportOnSize(countryList): result='' countryList.sort(key=sortKey) for cobj in countryList: result+=cobj.printAllOfMe()+'\n' return result #--------------------------- # testing the module if __name__=="__main__": clist=makeCountryList() print (reportOnSize(clist)) print (reportContinent(clist))
Det er en enkel sak å skrive om rapporteringen slik at vi får ut f.eks. et HTML-format. Hvis vi gjør dette og preparerer koden som et CGI-skript, få vi følgende: