Gå til innhold

Sliter med å forstå klasser("class") python


Anbefalte innlegg

Hei,

 

Er ganske ny til scripting i python og har til nå laget små scripts uten klasser men ser nå at det er nødvendig å bruke. Men jeg sliter virkelig med å forstå dem, jeg skjønner hvordan man lager dem men jeg skjønner ikke helt hvorfor man trenger dem og hvorfor det er bedre.

 

Sliter også å forstå __self__ og hva man skal putte i den.

 

Noen som vet om noen bra tutorials for å lære seg dette? Gjerne som forklarer hvorfor det er bedre å bruke klasser en kun funksjoner.

 

EDIT: Jeg mente såklart __init__

Endret av Salvesen.
Lenke til kommentar
Videoannonse
Annonse

Jeg programmerer en god del python, og jeg har aldri brukt __self__.

 

Årsaken til at man bruker klasser er rett og slett for å strukterere kode, og gjøre den mer lesbar. Du kunne fint løst alle de samme oppgavene med kun å prøve funksjoner - men ofte blir koden mer lesbar om objektorientering er brukt riktig. Dette forstår man etterhvert når man har begynt å forstå hvordan man lager og bruker klasser. Ofte blir det brukt slik at en klasse gjerne beskriver en bestemt ting, som f.eks. et hus. Og dermed kan du samle alle verdiene og funksjonaliteten knyttet til huset på en plass.

 

Om man f.eks. har en Gate-klasse, hus-klasse og personklasse kunne man kanskje i enkelte tilfelle hatt kode som dette

mitthus = minGate.getHus(nummer=12)
familie = mitthus.getBeboere()
nytt_familiemedlem = Person("Kari", female, age=0)
mitthid.leggTilBeboer(nytt_familiemedlem)

Du kan også prøve å lese mer her: http://code.tutsplus.com/articles/python-from-scratch-object-oriented-programming--net-21476

Endret av etse
Lenke til kommentar

__init__ brukes kun til å initialisere klassen. Det er ikke en funksjon som du vanligvis bruker manuelt, men brukes/kalles automatisk når du initaliserer klassen (med argumenter):

Argumentene i __init__ er de du initaliserer klassen med..

Tror det blir bedre med et eksempel:

class Point(object):
  # initialiserer klassen.. kalles kjeldent direkte.
  def __init__(self, x, y):
    self.x = x
    self.y = y
    
  # konverterer den til en text (slik at vi kan printe den)
  def __str__(self):
    return 'Point('+str(self.x)+','+str(self.y)+')'
 
  # standard funksjon
  def offset(self,x,y, lazy=True):
    if lazy:
      return Point(self.x+x, self.y+y)
    else:
      self.x += x;
      self.y += y;

 
 
pt = Point(31,10) #kaller Point.__init__(...) med 31, og 10.
print pt
  
print pt.offset(10,10)
Endret av slacky
Lenke til kommentar

 

__init__ brukes kun til å initialisere klassen. Det er ikke en funksjon som du vanligvis bruker manuelt, men brukes/kalles automatisk når du initaliserer klassen (med argumenter):

 

Argumentene i __init__ er de du initaliserer klassen med..

 

Tror det blir bedre med et eksempel:

class Point(object):
  # initialiserer klassen.. kalles kjeldent direkte.
  def __init__(self, x, y):
    self.x = x
    self.y = y
    
  # konverterer den til en text (slik at vi kan printe den)
  def __str__(self):
    return 'Point('+str(self.x)+','+str(self.y)+')'
 
  # standard funksjon
  def offset(self,x,y, lazy=True):
    if lazy:
      return Point(self.x+x, self.y+y)
    else:
      self.x += x;
      self.y += y;

 
 
pt = Point(31,10) #kaller Point.__init__(...) med 31, og 10.
print pt
  
print pt.offset(10,10)

Takker så mye for tilbakemelding folkens! Hva er egentlig poenget til å lage klasser? For å bruke deler av andre funksjoner i nye funksjoner?

 

Per i dag bruker jeg ikke klasser og prøver å finne ut hvorfor jeg burde bruke de.

Lenke til kommentar
Takker så mye for tilbakemelding folkens! Hva er egentlig poenget til å lage klasser? For å bruke deler av andre funksjoner i nye funksjoner?

este har svart på dette,det med OOP er stor tema som det kan sies mye om både på godt og vondt.

Du får nesten lese mer om dette,kan anbefale denne

Grei video med Raymond Hettinger,et par linker 1 2 3

 

For og pirke litt slacky,offset er ikke en "standard funksjon".

offest er en metode som tilhører class Point..

Skulle det vært en "standard funksjon" måtte man brukt @staticmethod.

 

Og return linjen med str() og +,synes jeg ikke ser bra ut.

#return 'Point('+str(self.x)+','+str(self.y)+')'
return 'Point({},{})'.format(self.x,self.y)
Endret av snippsat
  • Liker 1
Lenke til kommentar

Poenget med klasser er ikke noe annet enn å skrive ryddig, å sortere kode der det er relevant. Ofte får det nytte i større prosjekter.

 

La oss si du f.eks. ønsker å drive med vektor-matematikk i programmet ditt, da vil det ofte falle naturlig å lage en vektor-klasse, siden det er tingen du skal jobbe med. (ofte er det at noe kan regnes som en viktig ting et hint om at det kanskje kan ha en egen klasse).

 

Jeg lager dermed en enkel vektor-klasse som støtter funksjonaliteten å adderes og subtraheres med andre vektorer - samt den skal kunne ganges med en konstant. For enkelthets skyld ønsker jeg også å kunne vite lengden.

from __future__ import division
import math

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Vector(self.x+other.x, self.y+other.y)

    def __sub__(self, other):
        return Vector(self.x-other.x, self.y-other.y)

    def __mul__(self, constant):
        return Vector(self.x*constant, self.y*constant)

    def __div__(self, constant):
        return Vector(self.x/constant, self.y/constant)

    def length(self):
        return math.sqrt(self.x**2 + self.y**2)

    def __str__(self):
        return "Vector({}, {})".format(self.x, self.y)


vector_a = Vector(10, 10)
vector_b = Vector(10, 20)

print "Length of vector_a:", vector_a.length()
print "Length of vector_b:", vector_b.length()

vector_c = vector_b - vector_a
print "Distance between a and b:", vector_c.length()
print "The distance vector is:", vector_c

vector_d = vector_a + vector_b
print "Vector_a + Vector_b = {}, and has a length of {}".format(vector_d, vector_d.length())

På denne måten har jeg laget en vektor i språket, og kan bruke den akkurat som en vektor i normal matematikk. Plusse sammen 2 vektorer gir meg en ny vektor som er slik jeg forventer og å multiplisere den med et tall fungerer også akkurat slik man er vant med. På denne måten kan man skrive oversiktig kode.

 

Her er en eksempel på en implementasjon uten klasser:

from __future__ import division
import math

def vector_add(vector_a, vector_b):
    return (vector_a[0]+vector_b[0], vector_a[1]+vector_b[1])

def vector_sub(vector_a, vector_b):
    return (vector_a[0]-vector_b[0], vector_a[1]-vector_b[1])

def vector_multiplication(vector, constant):
    return (vector[0]*constant, vector[1]*constant)

def vector_division(vector, constant):
    return (vector[0]/constant, vector[1]/constant)

def get_vector_length(vector):
    return math.sqrt(vector[0]**2 + vector[1]**2)

def vector_to_string(vector):
    return "Vector({}, {})".format(vector[0], vector[1])


vector_a = (10, 10)
vector_b = (10, 20)

print "Length of vector_a:", get_vector_length(vector_a)
print "Length of vector_b:", get_vector_length(vector_b)

vector_c = vector_sub(vector_b, vector_a)
print "Distance between a and b:", get_vector_length(vector_c)
print "The distance vector is:", vector_to_string(vector_c)

vector_d = vector_add(vector_a, vector_b)
print "Vector_a + Vector_b = {}, and has a length of {}".format(vector_to_string(vector_d), get_vector_length(vector_d))
Endret av etse
Lenke til kommentar

Poenget med klasser er ikke noe annet enn å skrive ryddig

Dette er en konsekvens.

 

å sortere kode der det er relevant.

Nei.

 

Message passing yo. Den store motiverende faktoren er å abstrahere bort state og implementasjonsdetaljer.

Endret av Lycantrophe
  • Liker 1
Lenke til kommentar

Utover å skrive mer lesbar kode - som jeg kanskje feilaktig kallte ryddig kode, er det egentlig få eller ingen fordeler med å bruke objekt orientert programmering. Rent teknisk kan du implementere akkurat den samme funksjonaliteten helt uten objekter.

 

Med å sortere kode mente jeg her at en av de store fordelene med objekt-orientering at man f.eks. kan putte alle implementasjonsdetaljer rundt f.eks. vektor-regning i en vektorklasse og dermed ha "sortert" denne kodebiten, slik at den ligger på en plass det ville føles naturlig å ha den.

Lenke til kommentar

Utover å skrive mer lesbar kode - som jeg kanskje feilaktig kallte ryddig kode, er det egentlig få eller ingen fordeler med å bruke objekt orientert programmering.

Uenig. Det er plenty av problemer som løses pent med OO. Det er en helt kurant måte å håndtere tilstand på, og det å modellere ting med message passing gjør mange problemer greie å håndtere.

 

Rent teknisk kan du implementere akkurat den samme funksjonaliteten helt uten objekter.

Ja.

 

Med å sortere kode mente jeg her at en av de store fordelene med objekt-orientering at man f.eks. kan putte alle implementasjonsdetaljer rundt f.eks. vektor-regning i en vektorklasse og dermed ha "sortert" denne kodebiten, slik at den ligger på en plass det ville føles naturlig å ha den.

Jeg vet ikke om jeg helt liker bruken av ordet sortert her, men det kan jeg la ligge.
  • Liker 1
Lenke til kommentar
  • 3 måneder senere...

Utover å skrive mer lesbar kode - som jeg kanskje feilaktig kallte ryddig kode, er det egentlig få eller ingen fordeler med å bruke objekt orientert programmering. Rent teknisk kan du implementere akkurat den samme funksjonaliteten helt uten objekter.

 

Med å sortere kode mente jeg her at en av de store fordelene med objekt-orientering at man f.eks. kan putte alle implementasjonsdetaljer rundt f.eks. vektor-regning i en vektorklasse og dermed ha "sortert" denne kodebiten, slik at den ligger på en plass det ville føles naturlig å ha den.

 

Uenig. Det som er så genialt er at man kan deklarere et interface(ikke i Python, men du kan jo alltids definere funksjonene og enten "pass" eller kaste en NotImplemented). Da har man definert opp hvilke funksjoner som skal skrives og hva de skal returnere. Man kan f.eks ha IConfigReader som et interface. Deretter kan man ha klassene XmlConfigReader, DbConfigReader og IniConfigReader. Da er det enkelt å bytte rundt på de.

 

Klar over at dette ikke gjelder python etter som man ikke har interface etc definert opp, men er like mulig i python, men mye mer brukt i type-static språk.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...