logo
CGI
Objekter
Velkommen > Moduler > Python >Objekter
../../common/gfx/prev.gif ../../common/gfx/home.gif ../../common/gfx/next.gif

Objekter i Python

hvordan lage egne klasser og objekter

Hva:
Litt om egne klasser og objekter i Python
.

Moduler og klasser

Python opererer med moduler og objekter.

Moduler

Modulbegrepet er trolig inspirert av Pascal eller Modula. Vi vet at vi kan lage moduler med funksjoner og aksessere disse funksjonene ved hjelp av dot-notasjon. F.eks. slik:

import math
print math.sqrt(25)
        

Vi importerer modulen math og bruker funksjonen sqrt() som er definert i math. math er ikke en klasse, men en modul. I dette tilfellet brukte vi en standardmodul, men vi vet at vi kan lage våre egne moduler. Vi vet videre at vi kan aksessere, ikke bare funksjoner, men også globale variable i moduler. F.eks. slik:

import math
print math.sin(math.pi/2.0)
        

Det greieste er vel å betrakte moduler som en måte å ordne biblioteker på, selv om det i programkoden kan se ut som vi opererer mot objekter. Av og til har vi klasser i moduler. F.eks:

import datetime
now=datetime.date.today()
print now.year
mydate=datetime.date(1946,12,27)
print mydate.day
    

Vi bruker klassen date i modulen datetime. Vi bruker først den statiske funksjonen today() for å konstruere et date-objekt. Deretter lager vi et date-bjekt ved hjelp av en konstuktor som tar år, mnd, dag som input.

Klasser

Python er et objektorientert språk. Vi kan betrakte datatyper og innebygde datastrukturer som objekter.

Klasse begrepet i Python har endret seg. I Pythondokumentasjonen (language reference 3.3) uttrykkes dette slik: "Classes and instances come in two flavors: old-style or classic, and new-style."

Nedenfor skal vi se på noen svært enkle eksempler på egne klasser. Vi skal uttrykke oss i "new-style", men ikke gå spesielt dypt i materien. 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 kosntruksjon, 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 Javabeans.

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__()
ole.setName('Ole Jakob')
print ole.__str__()

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():
        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. Datasettet er beskrevet i modulen Noen datasett, og dataene er slik: land.txt

import urllib
"""
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='http://www.ia.hiof.no/~borres/commondata/geonames/land.txt'
        T=urllib.urlopen(surl).read()
        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:
        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 compareCountries(c1,c2):
    if c1.area < c2.area:
        return 1
    if c2.area < c1.area:
        return -1
    return 0
    
def reportOnSize(countryList):
    result=''
    countryList.sort(compareCountries)
    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:

+

Referanser og eksempler:

Pythondocumentasjonen (verson 2.5) er ikke oppdatert på det nye objektbegrepet
Se derfor: www.python.org/doc/newstyle.html

Geonames: www.geonames.org/

Produksjon, kontroll og vedlikehold:

B Stenseth, september 2007

Markup og web fra Høgskolen i Østfold: http://www.ia.hiof.no/~borres/ml/

../../common/gfx/prev.gif ../../common/gfx/home.gif ../../common/gfx/next.gif
skjema popup

Valid XHTML 1.0 Strict
popup card
Bygget med WXT