Mer om funktioner
Vi börjar med en snabbrepetition av funktioner i Python. Funktioner definieras med nyckelordet def
:
def meddelande():
print("Det här kommer från en funktion")
För att använda funktionen behöver vi anropa eller kalla på den i programmet:
meddelande()
I det här fallet skulle programmet skriva ut följande:
Det här kommer från en funktion
Parametrar och argument hos en funktion
En funktion kan ta emot en eller flera argument. När funktionen anropas tilldelas argumenten till variabler som är definierade i funktionsdefinitionen. Dessa variabler kallas parametrar och de listas inom de parenteser som kommer efter funktionens namn.
I den följande koden har funktionen halsa
en definierad parameter (namn), medan funktionen summa
har två (a och b):
def halsa(namn):
print("Hej,", namn)
def summa(a, b):
print("Summan av parametrarna är", a + b)
halsa("Emilia")
summa(2, 3)
Hej, Emilia Summan av parametrarna är 5
Felmeddelanden som uppstår i testerna
De flesta uppgifter under den här kursen inkluderar automatiska tester. Om programmet inte fungerar på det sätt som förutsätts av uppgiften, kommer testet att visa ett felmeddelande. Det här meddelandet kan vara till nytta – eller inte. Det är värt att läsa meddelandet noga.
I vissa fall berättar felmeddelandet inte särskilt mycket. I nästa övning kan du stöta på det här felmeddelandet:
Meddelandet berättar att man borde kunna köra funktionen streck
med de specificerade argumenten:
streck(5, "")
Det verkliga problemet får vi reda på när vi kör det funktionsanrop som står i felmeddelandet. Du kan göra det genom att kopiera funktionsanropet till ditt program och klicka på triangeln:
Den del av felmeddelandet som uppstår när programmet körs (markerade i bilden ovan) berättar att rad fyra i koden orsakar felet IndexError
. I den förra modulen fanns ett liknande exempel, där vi försökte använda ett index som inte var en del av en sträng. Den här gången orsakas problemet av att vi försöker hämta den första bokstaven hos en tom sträng – dvs. en sträng med längden noll.
Funktionsanrop inom funktionsanrop
Du kan anropa en funktion från en annan funktion. Vi har faktiskt gjort det redan flera gånger – vi har anropat print
-funktionen inom våra egna funktioner i den förra modulen. Våra egna funktioner fungerar på samma sätt. I det följande exemplet anropar funktionen halsa_flera_ganger
funktionen halsa
så många gånger som specificerats i argumentet ganger:
def halsa(namn):
print("Hej,", namn)
def halsa_flera_ganger(namn, ganger):
while ganger > 0:
halsa(namn)
ganger -= 1
halsa_flera_ganger("Emilia", 3)
Hej, Emilia Hej, Emilia Hej, Emilia
Funktioners returvärde
Funktioner kan också returnera värden. Till exempel returnerar Pythons inbyggda funktion input
den sträng som användaren har matat in. Värdet som returneras av en funktion kan lagras i en variabel:
ord = input("Ange ett ord: ")
När du vill få ett heltalsvärde av användaren måste det värde som hen matar in via input
konverteras till ett heltal. För det använder vi int
-funktionen som också returnerar ett värde:
siffra = int(input("Ange ett heltal: "))
Funktionen int
tar den sträng som returneras av input
-funktionen som argument och returnerar – om möjligt – värdet i heltalsform.
return
-satsen
Funktioner som du själv definierar kan också returnera värden. För det här ändamålet behöver du använda return
-satsen. Till exempel returnerar funktionen summa
nedan summan av dess parametrar:
def summa(a, b):
return a + b
svar = summa(2, 3)
print("Summa:", svar)
Summa: 5
Här är ett annat exempel på ett returnerat värde. Funktionen ber om användarens namn och returnerar den sträng som användaren matar in:
def fraga_namn():
namn = input("Vad är ditt namn? ")
return namn
namn = fraga_namn()
print("Hej,", namn)
Vad är ditt namn? Anna Hej, Anna
Observera att return
-satsen avbryter funktionen, och gör så att programmet fortsätter köras i huvudfunktionen. Det här är ett sätt att göra en jämförelsefunktion:
def minst(a,b):
if a < b:
return a
return b
print(minst(3, 7))
print(minst(5, 2))
Idén är att om a
är mindre än b
så kommer funktionen att returnera a
och avslutas direkt. Annars fortsätter man till nästa rad som returnerar värdet b
. Det går alltså inte att köra två return
-satser i samma funktion under samma funktionsanrop, eftersom den första return
-satsen första kommer att avbryta funktionen.
3 2
Du kan använda dig av return
-satsen även om funktionen inte returnerar något värde. Då är dess uppgift helt enkelt att avsluta funktionskörningen:
def halsa(namn):
if namn == "":
print("???")
return
print("Hej,", namn)
halsa("Emilia")
halsa("")
halsa("Mårten")
Om argumentet som sparas i variabeln namn
är en tom sträng, kommer texten ???
att skrivas ut och funktionen avslutas:
Hej, Emilia ??? Hej, Mårten
Att använda returvärden från funktioner
Vi känner redan till att värden som returneras från funktioner kan lagras i variabler:
def summa(a, b):
return a + b
resultat = summa(4, 6)
print("Summan är", resultat)
Summan är 10
Returvärdet hos en funktion kan jämföras med vilket som helst annat värde. Det är inte nödvändigt att lagra värdet i en variabel för att ge det som argument till print
-instruktionen:
print("Summan är", summa(4, 6))
Returvärdet hos en funktion kan vara ett argument för en funktion:
def summa(a, b):
return a+b
def differens(a, b):
return a-b
resultat = differens(summa(5, 2), summa(2, 3))
print("Svaret är", resultat)
Svaret är 2
I det här fallet körs de inre funktionsanropen summa(5, 2)
och summa(2, 3)
först. Värdena som returneras (7 och 5) används som argument för det yttre funktionsanropet.
Det yttre funktionsanropet differens(7, 5)
returnerar värdet 2, som lagras i variabeln resultat
och skrivs ut.
För att sammanfatta: värden som returneras av funktioner fungerar som alla andra värden i Python. De kan skrivas ut, lagras i variabler och användas i uttryck och som argument i funktionsanrop.
Skillnaden mellan return
och print
Ibland är skillnaden mellan att använda return
och print
inte helt uppenbar. Vi undersöker två olika sätt att skapa en funktion som berättar vilket av två värden är större:
def max1(a, b):
if a > b:
return a
else:
return b
def max2(a, b):
if a > b:
print(a)
else:
print(b)
svar = max1(3, 5)
print(svar)
max2(7, 2)
5 7
Båda versionerna verkar fungera i och med att det större värdet skrivs ut korrekt. Det finns ändå en central skillnad mellan de två funktionerna. Den första, max1
, skriver inte ut något. Den använder sig istället av return
-satsen. Om vi kör den följande kodraden…
max1(3, 5)
…verkar ingenting hända. Funktionens returvärde måste användas på något sätt i den kod som anropar funktionen. Det kan till exempel lagras i en variabel och skrivas ut:
svar = max1(3, 5)
print(svar)
Om man inte behöver värdet för något annat ändamål i koden, kan man också skriva ut det direkt:
print(max1(3, 5))
Den andra versionen, max2
, använder sig av print
-instruktionen inom funktionen. Om vi vill se resultatet på skärmen, kan vi helt enkelt anropa funktionen…
max2(7, 5)
…varpå det större värdet kommer att skrivas ut. Det dåliga med den här funktionen är att värdet som funktionen räknar ut inte lagras någonstans och därmed inte kan användas av själva programmet. Därför är funktioner som returnerar ett värde ofta ett bättre alternativ.
Argumentets typ
Här är en kort repetition av de datatyper vi bekantat oss med hittills:
Tyyppi | I Python | Exempel |
---|---|---|
Heltal | int | 23 |
Flyttal | float | -0.45 |
Sträng | str | "Petra Python" |
Sanningsvärde (Boolean) | bool | True |
När du anropar en funktion, kommer den endast att fungera korrekt då argumenten du ger åt den är av korrekt typ. Ta en titt på det här exemplet:
def skriv_ut_flera_ganger(meddelande, ganger):
while ganger > 0:
print(meddelande)
ganger -= 1
Funktionen fungerar korrekt om vi anropar den på följande sätt:
skriv_ut_flera_ganger("Hejsan", 5)
Hejsan Hejsan Hejsan Hejsan Hejsan
Om vi däremot ger funktionen ett argument av fel typ så kommer den inte att fungera:
skriv_ut_flera_ganger("Hejsan", "Emilia")
TypeError: '>' not supported between instances of 'str' and 'int'
Problemet här är att den andra parametern ganger
jämförs med ett heltal (0) i while
-loopens villkorsuttryck (på den andra raden i funktionsdefinitionen). Det givna argumentet "Emilia"
är dock en sträng och inte ett heltal. Strängar och heltal kan inte jämföras så här enkelt – därav felmeddelandet.
För att undvika den här typen av problem kan du inkludera typledtrådar (type hints) när du definierar funktioner. Typledtråden berättar vilken typ av argument funktionen förväntar sig:
def skriv_ut_flera_ganger(meddelande : str, ganger : int):
while ganger > 0:
print(meddelande)
ganger -= 1
Det här berättar för alla som använder funktionen att det första argumentet som skickas till funktionen ska vara en sträng och det andra ett heltal.
Också returvärdets typ kan specificeras när funktionen definieras:
def fraga_namn() -> str:
namn = input("Vad är ditt namn? ")
return namn
Det här berättar för användaren att funktionen kommer att returnera en sträng.
Obs! Typledtrådar är bokstavligen ledtrådar. Det är inte en garanti och kan inte säkerställa att felaktiga datatyper inte ges till eller returneras av en funktion. Om det här sker kommer funktionen ändå att köras, med resultatet att den inte nödvändigtvis fungerar korrekt.
Log in to view the quiz
Se dina poäng genom att klicka på cirkeln nere till höger av sidan.