Vinnaren i pepparkakshustävlingen!
2015-09-21, 21:50
  #1
Medlem
Yppsilons avatar
Hej!

Jag kör sommarkursen i programmering för Python, och skulle behöva en mer grundläggande samt genomgående beskrivning i hur alla attributen och parametrar relateras mellan en klass och dess metoder.

Vet ni någon bra kurslitteratur eller hemsida som successivt och långsamt går igenom detta? Skulle uppskattas enormt!
Citera
2015-09-21, 22:08
  #2
Medlem
thehater123s avatar
Är det något specifikt du inte förstår?

Klass: Ritning av ett objekt
Instans: Det faktiska objektet

En klass kan ha många instanser.

Vid anrop till en metod skickas en pekare (self i python) med som pekar till objektets instans så att du kan komma åt objektets instansvariabler (också kallade fältvariabler) samt övriga metoder i objektet.

Arv och polymorphism kan du läsa om på wikipedia. Just för python är just polymorphism inte så tyligt eftersom python använder sig av duck-typing, dvs. "om den kan kvacka som en anka så antar vi att det är en anka". Problemet är att man då får alla fel i runtime, till skillnad i från java eller C++ där man upptäcker felen tidigare när man kompilerar programmet. Python är altså dynamiskt, men mycket "farligare" att programmera i, då alla typfel måste hittas medans man kör programmet.

Du kan tänka dig ett objekt som en bil t.ex. den har en metod, öppna dörr.
Bilen består av flera andra objekt, dörrar, däck osv som är dess komponenter.
Därför kallas detta för "composition" inom objektorientering.

Böcker finns det gott om på typ amazon. Jag har dock aldrig ägt en python bok.
__________________
Senast redigerad av thehater123 2015-09-21 kl. 22:19.
Citera
2015-09-21, 23:22
  #3
Medlem
Yppsilons avatar
Det är mer syntaxen jag har svårt att greppa.

Citat:
class Kakmonster:
'Håller reda på hur många kakor som en person har ätit'
kakburk = 0
def __init__(self, namn):
self.namn = namn
self.ätna_kakor = 0
def __str__(self):
return self.namn + ' har ätit ' + str(self.ätna_kakor) + ' kakor.'
def ät_kaka(self):
self.ätna_kakor += 1
Kakmonster.kakburk -= 1
Kakmonster.kakburk = 3

namn = input("Hej, vad heter du? ")
person = Kakmonster(namn)

while Kakmonster.kakburk != 0:
svar = input("Vill du äta en kaka? ")
if svar.lower().startswith('j'):
person.ät_kaka()
print(person)
print("Kvar i kakburken: ", Kakmonster.kakburk)


Varför ska en klass initieras med __init__?

Varför har vi self i __init__ som parameter?

Om jag skriver globalt.
person = Klassen(parameter), vad har jag egentligen gjort här? Hur får programmet self=person i anroppen senare? Och hur fungerar self.namn = namn...?

Metoder/funktionerna är jag rätt säker på. Men hur klassen hanterar funktioner, och hur man anropar en klass fattar jag inte...
__________________
Senast redigerad av Yppsilon 2015-09-21 kl. 23:27.
Citera
2015-09-21, 23:45
  #4
Medlem
thehater123s avatar
init är en konstruktor.
Den kallas först när du skapar objektet för att initiera saker.

self används för att sätta fältvariabler i objektet. I python behöver du inte deklarera dessa, men hade det varit t.ex. java så hade du gjort.

Kod:
public class Kakmonster {
   private String namn;

   public Kakmonster(String namn) {
      this.namn = namn;
   }
 ...
}

Det är lite tydligare vad som händer här. Du har en variabel namn som skickas in i konstruktorn (i java heter den inte init utan namnet på klassen), och för att skilja mellan namn som ligger i objektet och namn som variabel i konstruktorn används this. This är samma sak som self i python.

I java behöver du inte använda this heller, nedan är t.ex. helt okej:

Kod:
public class Kakmonster {
   private String kakNamn;

   public Kakmonster(String namn) {
      kakNamn = namn;
   }
 ...
}

I python måste du använda self dock. Self skickas med i alla anrop till metoder på objekt, precis som this skickas med i smyg i java. I python så är self synlig, du måste deklarera den som en parameter i dina metoder.

This och self refererar till objektet som du arbetar med.

Du kan anropa metoder "på dej själv" mha. self t.ex. genom self.ät_kaka() precis som du kan göra person.ät_kaka() när du har tilldelat instansen till variabeln person.

Du förstår, init retunerar "self" när den är klar. Init är egentligen metoden Kakmonster(String namn) som du anropar nedan för att skapa en instans av Kakmonster. Self skickas med implicit, precis som den skickas med implicit när du gör person.ät_kaka()

Egentligen så gör python ät_kaka(person) när du skriver person.ät_kaka(). Person pekar på objektet, vilket då blir self inne i metoden.

Sorry om jag krånglade till det nu, haha.

Kakmonster.kakburk är ett specialfall. Där refererar du till kakburk som ligger i klassen och inte i instansen.

I java hade man deklarerat kakburk som static. Du får läsa på skillnaden mellan instansvariabler och statiska variabler i klasser. Instansvariabler finns med i varje instans du skapar, varje "Kakmonster" objekt t.ex., men kakburk är delad mellan alla kakmonster och ligger i klassen inte i dom enskilda kakmonster objekten.
__________________
Senast redigerad av thehater123 2015-09-22 kl. 00:05.
Citera
2015-09-22, 00:11
  #5
Medlem
Yppsilons avatar
Så om jag förstår detta rätt..

Self. används inne i klassen som den generella parametern till alla metoder? När jag tilldelat som
person = Kakmonster() så gör jag "person" till ett objekt som byts ut mot "self" inne i klassen?

I __init__ så har jag (self, namn). Vad händer när jag gör self.namn = namn? Blir lite virrig av detta

Haha har så många frågor..Men försöker hålla dem konkreta. Hittar en avvägning mellan att klura ut men också fråga det som bara tar onödigt med tid att klura ut..
Citera
2015-09-22, 00:12
  #6
Medlem
thehater123s avatar
Jag kan ju också tillägga att jag tror att det är lättare att lära sig objektorientering i Java än i Python. I Java är allting klasser, och det är typat och mer rent och tydligt.

I Python kan du göra lite som du vill, det är mer otydligt hur saker fungerar.
__________________
Senast redigerad av thehater123 2015-09-22 kl. 00:35.
Citera
2015-09-22, 00:17
  #7
Medlem
thehater123s avatar
Citat:
Ursprungligen postat av Yppsilon
person = Kakmonster("Charlie")
Här skapar du ett nytt kakmonster som har namnet Charlie. Detta kakmonster tilldelas till variabeln person. person håller nu en referens till kakmonstret med namn "Charlie".

Init kallas med namnet "Charlie" i det här fallet, self blir en referens till det nya kakmonstret.

Citat:
Ursprungligen postat av Yppsilon
I __init__ så har jag (self, namn). Vad händer när jag gör self.namn = namn?

Här tillderlar du en variabel namn som ligger i kakmonstret med värdet som du får in från variablen namn i init metoden.

Init är precis som alla andra metoder, den tar två argument, self och namn.
Men du vill ju spara namn i kakmonsterinstansen som du håller på och skapar.
Det gör du med hjälp av self.

så, "self.namn" refererar till variabeln namn i din kakmonsterinstans
och bara "namn" är variabeln som kommer från init metodens parameterlista.
__________________
Senast redigerad av thehater123 2015-09-22 kl. 00:41.
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback