# 4. Fler verktyg för kontrollflöde

Förutom `while` som just introducerades använder Python några fler som vi kommer att stöta på i det här kapitlet.

## 4.1. `if`-satser

Den kanske mest välkända typen av uttalande är `if`-satsen. Till exempel:

    >>> x = int(input("Ange ett heltal: "))
    Ange ett heltal: 42
    >>> if x < 0:
    ...     x = 0
    ...     print('Negative changed to zero')
    ... elif x == 0:
    ...     print('Zero')
    ... elif x == 1:
    ...     print('Single')
    ... else:
    ...     print('More')
    ...
    More

Det kan finnas noll eller fler `elif`-delar, och `else`-delen är valfri. Nyckelordet ’`elif`’ är en förkortning för ’else if’, och är användbart för att undvika överdriven indragning. En `if` … `elif` … `elif` … sekvens är ett substitut för `switch` eller `case`-satser som finns i andra språk.

Om du jämför samma värde med flera konstanter, eller kontrollerar specifika typer eller attribut, kan du också ha nytta av `match`. För mer information se match-satser.

## 4.2. `for`-satser

Satsen `for` i Python skiljer sig lite från vad du kanske är van vid i C eller Pascal. I stället för att alltid iterera över en aritmetisk progression av tal (som i Pascal), eller ge användaren möjlighet att definiera både iterationssteget och stoppvillkoret (som i C), itererar Pythons `for`-sats över objekten i en sekvens (en lista eller en sträng), i den ordning som de förekommer i sekvensen. Till exempel (ingen ordvits avsedd):

    >>> # Measure some strings:
    >>> words = ['cat', 'window', 'defenestrate']
    >>> for w in words:
    ...     print(w, len(w))
    ...
    cat 3
    window 6
    defenestrate 12

Kod som ändrar en samling samtidigt som den itererar över samma samling kan vara knepig att få rätt. Istället är det vanligtvis enklare att loopa över en kopia av samlingen eller att skapa en ny samling:

    # Create a sample collection
    users = {'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}

    # Strategy:  Iterate over a copy
    for user, status in users.copy().items():
        if status == 'inactive':
            del users[user]

    # Strategy:  Create a new collection
    active_users = {}
    for user, status in users.items():
        if status == 'active':
            active_users[user] = status

## 4.3. Funktionen :func:`range

Om du behöver iterera över en sekvens av tal är den inbyggda funktionen `range()` praktisk. Den genererar aritmetiska progressioner:

    >>> for i in range(5):
    ...     print(i)
    ...
    0
    1
    2
    3
    4

Den angivna slutpunkten är aldrig en del av den genererade sekvensen; `range(10)` genererar 10 värden, de lagliga indexen för objekt i en sekvens med längden 10. Det är möjligt att låta intervallet börja vid ett annat tal, eller att ange ett annat steg (även negativt; ibland kallas detta för ”steg”):

    >>> list(range(5, 10))
    [5, 6, 7, 8, 9]

    >>> list(range(0, 10, 3))
    [0, 3, 6, 9]

    >>> list(range(-10, -100, -30))
    [-10, -40, -70]

För att iterera över indexen i en sekvens kan du kombinera `range()` och `len()` på följande sätt:

    >>> a = ['Mary', 'had', 'a', 'little', 'lamb']
    >>> for i in range(len(a)):
    ...     print(i, a[i])
    ...
    0 Mary
    1 had
    2 a
    3 little
    4 lamb

I de flesta sådana fall är det dock lämpligt att använda funktionen `enumerate()`, se Looping-tekniker.

En märklig sak händer om man bara skriver ut ett range:

    >>> range(10)
    range(0, 10)

På många sätt beter sig objektet som returneras av `range()` som om det vore en lista, men det är det faktiskt inte. Det är ett objekt som returnerar de successiva objekten i den önskade sekvensen när du itererar över det, men det gör inte listan, vilket sparar utrymme.

Vi säger att ett sådant objekt är iterable, det vill säga lämpligt som mål för funktioner och konstruktioner som förväntar sig något från vilket de kan få successiva objekt tills tillgången är uttömd. Vi har sett att `for`-satsen är en sådan konstruktion, medan ett exempel på en funktion som tar en iterabel är `sum()`:

    >>> sum(range(4))  # 0 + 1 + 2 + 3
    6

Later we will see more functions that return iterables and take iterables as arguments. In chapter Datastrukturer, we will discuss `list()` in more detail.

## 4.4. `break` och `continue`-satser

Satsen `break` bryter ut ur den innersta omslutande `for`- eller `while`-slingan:

    >>> for n in range(2, 10):
    ...     for x in range(2, n):
    ...         if n % x == 0:
    ...             print(f"{n} equals {x} * {n//x}")
    ...             break
    ...
    4 equals 2 * 2
    6 equals 2 * 3
    8 equals 2 * 4
    9 equals 3 * 3

Satsen `continue` fortsätter med nästa iteration av slingan:

    >>> for num in range(2, 10):
    ...     if num % 2 == 0:
    ...         print(f"Found an even number {num}")
    ...         continue
    ...     print(f"Found an odd number {num}")
    ...
    Found an even number 2
    Found an odd number 3
    Found an even number 4
    Found an odd number 5
    Found an even number 6
    Found an odd number 7
    Found an even number 8
    Found an odd number 9

## 4.5. `else`-klausuler på loopar

I en `for`- eller `while`-slinga kan `break`-satsen paras ihop med en `else`-sats. Om slingan avslutas utan att `break` exekveras, exekveras `else` klausulen.

I en `for`-slinga utförs `else`-satsen efter att slingan har avslutat sin sista iteration, dvs. om ingen paus inträffade.

I en `while`-loop körs den efter att loopens villkor blir falskt.

I båda typerna av slingor kommer `else`-klausulen inte att exekveras om slingan avslutades med `break`. Naturligtvis kommer andra sätt att avsluta slingan tidigt, till exempel ett `return` eller ett undantag, också att hoppa över exekveringen av `else`-satsen.

Detta exemplifieras i följande `for`-slinga, som söker efter primtal:

    >>> for n in range(2, 10):
    ...     for x in range(2, n):
    ...         if n % x == 0:
    ...             print(n, 'equals', x, '*', n//x)
    ...             break
    ...     else:
    ...         # loop fell through without finding a factor
    ...         print(n, 'is a prime number')
    ...
    2 is a prime number
    3 is a prime number
    4 equals 2 * 2
    5 is a prime number
    6 equals 2 * 3
    7 is a prime number
    8 equals 2 * 4
    9 equals 3 * 3

(Ja, detta är den korrekta koden. Titta noga: `else`-klausulen hör till `for`-slingan, inte `if`-satsen)

Ett sätt att tänka på else-klausulen är att föreställa sig att den paras ihop med `if` inuti slingan. När slingan körs kommer den att köra en sekvens som if/if/if/else. `if` är inne i slingan och påträffas ett antal gånger. Om villkoret någonsin är sant, kommer ett `break` att ske. Om villkoret aldrig är sant kommer `else`-klausulen utanför slingan att utföras.

När `else`-satsen används i en loop har den mer gemensamt med `else`-satsen i en `try`-sats än med `if`-satser: `try`-satsens `else`-sats körs när inget undantag inträffar, och en loops `else`-sats körs när inget `break` inträffar. För mer information om `try`-satsen och undantag, se Handling Exceptions.

## 4.6. `pass`-satser

Satsen `pass` gör ingenting. Det kan användas när ett uttalande krävs syntaktiskt men programmet inte kräver någon åtgärd. Till exempel:

    >>> while True:
    ...     pass  # Busy-wait for keyboard interrupt (Ctrl+C)
    ...

Detta används ofta för att skapa minimala klasser:

    >>> class MyEmptyClass:
    ...     pass
    ...

Ett annat ställe där `pass` kan användas är som en platshållare för en funktion eller en villkorlig kropp när du arbetar med ny kod, så att du kan fortsätta tänka på en mer abstrakt nivå. Nyckelordet:!pass ignoreras i tysthet:

    >>> def initlog(*args):
    ...     pass   # Remember to implement this!
    ...

För det sista fallet använder många människor ellipsen `...` istället för `pass`. Denna användning har ingen speciell betydelse för Python och är inte en del av språkdefinitionen (du kan använda vilket konstantuttryck som helst här), men `...` används konventionellt som en platshållarkropp också. Se Ellipsis-objektet.

## 4.7. `match`-satser

En `match`-sats tar ett uttryck och jämför dess värde med på varandra följande mönster som anges som ett eller flera fallblock. Detta är ytligt sett likt en switch-sats i C, Java eller JavaScript (och många andra språk), men det är mer likt mönstermatchning i språk som Rust eller Haskell. Endast det första mönstret som matchar exekveras och det kan också extrahera komponenter (sekvenselement eller objektattribut) från värdet till variabler. Om inget fall matchar exekveras ingen av grenarna.

Den enklaste formen jämför ett ämnesvärde mot en eller flera literaler:

    def http_error(status):
        matcha status:
            fall 400:
                returnera "Dålig förfrågan"
            fall 404:
                returnera "Hittades inte"
            fall 418:
                returnera "Jag är en tekanna"
            fall _:
                returnerar "Något är fel med internet"

Observera det sista blocket: ”variabelnamnet” `_` fungerar som ett wildcard och misslyckas aldrig med att matcha.

Du kan kombinera flera literaler i ett enda mönster med hjälp av `|` (”eller”):

    fall 401 | 403 | 404:
        return "Inte tillåtet"

Mönster kan se ut som uppackningsuppdrag och kan användas för att binda variabler:

    # punkten är en (x, y) tupel
    matcha punkten:
        fall (0, 0):
            print("Ursprung")
        fall (0, y):
            print(f"Y={y}")
        fall (x, 0):
            print(f"X={x}")
        fall (x, y):
            print(f"X={x}, Y={y}")
        fall _:
            raise ValueError("Inte en punkt")

Studera den här noggrant! Det första mönstret har två literaler och kan ses som en utvidgning av det literala mönstret ovan. Men de två följande mönstren kombinerar en bokstav och en variabel, och variabeln binder ett värde från ämnet (`point`). Det fjärde mönstret fångar två värden, vilket gör att det konceptuellt liknar uppackningsuppdraget `(x, y) = point`.

Om du använder klasser för att strukturera dina data kan du använda klassnamnet följt av en argumentlista som liknar en konstruktor, men med möjlighet att fånga attribut i variabler:

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

    def where_is(point):
        match point:
            case Point(x=0, y=0):
                print("Origin")
            case Point(x=0, y=y):
                print(f"Y={y}")
            case Point(x=x, y=0):
                print(f"X={x}")
            case Point():
                print("Somewhere else")
            case _:
                print("Not a point")

Du kan använda positionella parametrar med vissa inbyggda klasser som ger en ordning för sina attribut (t.ex. dataklasser). Du kan också definiera en specifik position för attribut i mönster genom att ställa in specialattributet `__match_args__` i dina klasser. Om det är inställt på (”x”, ”y”) är följande mönster alla likvärdiga (och alla binder attributet `y` till variabeln `var`):

    Punkt(1, var)
    Punkt(1, y=var)
    Punkt(x=1, y=var)
    Punkt(y=var, x=1)

Ett rekommenderat sätt att läsa mönster är att se dem som en utökad form av vad du skulle lägga till vänster om en tilldelning, för att förstå vilka variabler som skulle sättas till vad. Endast de fristående namnen (som `var` ovan) tilldelas av en match-sats. Prickade namn (som `foo.bar`), attributnamn (`x=` och `y=` ovan) eller klassnamn (som känns igen på ”(…)” bredvid dem, som `Point` ovan) tilldelas aldrig.

Mönster kan vara godtyckligt nästlade. Om vi till exempel har en kort lista med punkter, med `__match_args__` tillagt, kan vi matcha den så här:

    class Point:
        __match_args__ = ('x', 'y')
        def __init__(self, x, y):
            self.x = x
            self.y = y

    match points:
        case []:
            print("No points")
        case [Point(0, 0)]:
            print("The origin")
        case [Point(x, y)]:
            print(f"Single point {x}, {y}")
        case [Point(0, y1), Point(0, y2)]:
            print(f"Two on the Y axis at {y1}, {y2}")
        case _:
            print("Something else")

Vi kan lägga till en ”om”-klausul i ett mönster, en s.k. ”guard”. Om guarden är falsk går `match` vidare till att prova nästa fallblock. Observera att värdeinfångning sker innan guarden utvärderas:

    matcha punkt:
        case Point(x, y) if x == y:
            print(f"Y=X vid {x}")
        fall Punkt(x, y):
            print(f"Inte på diagonalen")

Flera andra viktiga egenskaper i detta uttalande:

- Precis som uppackningsuppdrag har tuple- och listmönster exakt samma betydelse och matchar faktiskt godtyckliga sekvenser. Ett viktigt undantag är att de inte matchar iteratorer eller strängar.

- Sekvensmönster stöder utökad uppackning: `[x, y, *rest]` och `(x, y, *rest)` fungerar på liknande sätt som uppackningsuppdrag. Namnet efter `*` kan också vara `_`, så `(x, y, *_)` matchar en sekvens med minst två objekt utan att binda de återstående objekten.

- Mappningsmönster: `{"bandwidth": b, "latency": l}` fångar värdena `"bandwidth"` och `"latency"` från en ordbok. Till skillnad från sekvensmönster ignoreras extra nycklar. En uppackning som `**rest` stöds också. (Men `**_` skulle vara överflödigt, så det är inte tillåtet)

- Undermönster kan fångas upp med hjälp av nyckelordet `as`:

      case (Punkt(x1, y1), Punkt(x2, y2) som p2): ...

  kommer att fånga det andra elementet i inmatningen som `p2` (så länge inmatningen är en sekvens av två punkter)

- De flesta literaler jämförs med likhet, men singletonerna `True`, `False` och `None` jämförs med identitet.

- Patterns may use named constants. These must be dotted names to prevent them from being interpreted as capture variables:

      from enum import Enum
      klass Färg(Enum):
          RED = 'röd'
          GREEN = 'grön'
          BLUE = 'blå'

      color = Color(input("Ange ditt val av 'röd', 'blå' eller 'grön': "))

      matcha färg:
          fall Color.RED:
              print("Jag ser rött!")
          fall Färg.GRÖN:
              print("Gräs är grönt")
          fall Färg.BLÅ:
              print("Jag känner mig nedstämd :(")

För en mer detaljerad förklaring och ytterligare exempel kan du titta på PEP 636 som är skriven i ett handledningsformat.

## 4.8. Definiera funktioner

Vi kan skapa en funktion som skriver Fibonacci-serien till en godtycklig gräns:

    >>> def fib(n):    # write Fibonacci series less than n
    ...     """Print a Fibonacci series less than n."""
    ...     a, b = 0, 1
    ...     while a < n:
    ...         print(a, end=' ')
    ...         a, b = b, a+b
    ...     print()
    ...
    >>> # Now call the function we just defined:
    >>> fib(2000)
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

Nyckelordet `def` introducerar en funktions definition. Det måste följas av funktionsnamnet och den parentesförsedda listan med formella parametrar. De satser som bildar funktionens kropp börjar på nästa rad och måste vara indragna.

Den första satsen i funktionens kropp kan eventuellt vara en stränglitteral; denna stränglitteral är funktionens dokumentationssträng, eller docstring. (Mer om docstrings finns i avsnittet Dokumentation Strängar.) Det finns verktyg som använder docstrings för att automatiskt producera dokumentation på nätet eller i tryck, eller för att låta användaren interaktivt bläddra igenom kod; det är god praxis att inkludera docstrings i kod som du skriver, så gör det till en vana.

När en funktion exekveras introduceras en ny symboltabell som används för funktionens lokala variabler. Närmare bestämt lagrar alla variabeltilldelningar i en funktion värdet i den lokala symboltabellen, medan variabelreferenser först letar i den lokala symboltabellen, sedan i de lokala symboltabellerna för omslutande funktioner, sedan i den globala symboltabellen och slutligen i tabellen med inbyggda namn. Globala variabler och variabler i inneslutande funktioner kan alltså inte direkt tilldelas ett värde inom en funktion (såvida inte globala variabler namnges i en `global`-sats eller variabler i inneslutande funktioner namnges i en `nonlocal`-sats), men de kan refereras.

De faktiska parametrarna (argumenten) till ett funktionsanrop introduceras i den lokala symboltabellen för den anropade funktionen när den anropas; argument skickas alltså med call by value (där värdet alltid är en referens till ett objekt, inte objektets värde). [När en funktion anropar en annan funktion, eller anropar sig själv rekursivt, skapas en ny lokal symboltabell för det anropet.

En funktionsdefinition associerar funktionsnamnet med funktionsobjektet i den aktuella symboltabellen. Tolken känner igen det objekt som pekas ut av namnet som en användardefinierad funktion. Andra namn kan också peka på samma funktionsobjekt och kan också användas för att komma åt funktionen:

    >>> fib
    <function fib at 10042ed0>
    >>> f = fib
    >>> f(100)
    0 1 1 2 3 5 8 13 21 34 55 89

Om du kommer från andra språk kanske du invänder att `fib` inte är en funktion utan en procedur eftersom den inte returnerar något värde. Faktum är att även funktioner utan `return`-sats returnerar ett värde, om än ett ganska tråkigt sådant. Detta värde kallas `None` (det är ett inbyggt namn). Att skriva värdet `None` undertrycks normalt av tolken om det skulle vara det enda värde som skrivs. Du kan se det om du verkligen vill med hjälp av `print()`:

    >>> fib(0)
    >>> print(fib(0))
    None

Det är enkelt att skriva en funktion som returnerar en lista med siffrorna i Fibonacci-serien, istället för att skriva ut den:

    >>> def fib2(n):  # return Fibonacci series up to n
    ...     """Return a list containing the Fibonacci series up to n."""
    ...     result = []
    ...     a, b = 0, 1
    ...     while a < n:
    ...         result.append(a)    # see below
    ...         a, b = b, a+b
    ...     return result
    ...
    >>> f100 = fib2(100)    # call it
    >>> f100                # write the result
    [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

I det här exemplet demonstreras som vanligt några nya Python-funktioner:

- Satsen `return` returnerar med ett värde från en funktion. `return` utan ett uttrycksargument returnerar `None`. Att falla av i slutet av en funktion returnerar också `None`.

- Satsen `result.append(a)` anropar en metod i listobjektet `result`. En metod är en funktion som ”hör till” ett objekt och som kallas `obj.metodnamn`, där `obj` är ett objekt (det kan vara ett uttryck) och `metodnamn` är namnet på en metod som definieras av objektets typ. Olika typer definierar olika metoder. Metoder av olika typer kan ha samma namn utan att det blir tvetydigt. (Det är möjligt att definiera egna objekttyper och metoder med hjälp av classes, se Klasser) Metoden `append()` i exemplet är definierad för listobjekt; den lägger till ett nytt element i slutet av listan. I det här exemplet är den likvärdig med `result = result + [a]`, men mer effektiv.

## 4.9. Mer om att definiera funktioner

Det är också möjligt att definiera funktioner med ett variabelt antal argument. Det finns tre former som kan kombineras.

### 4.9.1. Standardargumentvärden

Den mest användbara formen är att ange ett standardvärde för ett eller flera argument. Detta skapar en funktion som kan anropas med färre argument än vad den är definierad att tillåta. Till exempel:

    def ask_ok(prompt, retries=4, reminder='Please try again!'):
        while True:
            reply = input(prompt)
            if reply in {'y', 'ye', 'yes'}:
                return True
            if reply in {'n', 'no', 'nop', 'nope'}:
                return False
            retries = retries - 1
            if retries < 0:
                raise ValueError('invalid user response')
            print(reminder)

Denna funktion kan anropas på flera olika sätt:

- ger bara det obligatoriska argumentet: `ask_ok('Vill du verkligen sluta?')`

- som ger ett av de valfria argumenten: `ask_ok('OK att skriva över filen?', 2)``

- eller till och med ge alla argument: `ask_ok('OK att skriva över filen?', 2, 'Kom igen, bara ja eller nej!')`

I detta exempel introduceras också nyckelordet `in`. Detta testar om en sekvens innehåller ett visst värde eller inte.

Standardvärdena utvärderas vid tidpunkten för funktionsdefinitionen i det definierande omfånget, så att

    i = 5

    def f(arg=i):
        print(arg)

    i = 6
    f()

kommer att skriva ut `5`.

Viktig varning: Standardvärdet utvärderas bara en gång. Detta gör skillnad när standardvärdet är ett föränderligt objekt, t.ex. en lista, en ordbok eller instanser av de flesta klasser. Följande funktion ackumulerar t.ex. de argument som skickas till den vid efterföljande anrop:

    def f(a, L=[]):
        L.append(a)
        return L

    print(f(1))
    print(f(2))
    print(f(3))

Detta kommer att skrivas ut

    [1]
    [1, 2]
    [1, 2, 3]

Om du inte vill att standardvärdet ska delas mellan efterföljande anrop kan du istället skriva funktionen så här:

    def f(a, L=None):
        if L is None:
            L = []
        L.append(a)
        return L

### 4.9.2. Argument för nyckelord

Funktioner kan också anropas med nyckelordsargument av formen `kwarg=värde`. Till exempel kan följande funktion:

    def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
        print("-- This parrot wouldn't", action, end=' ')
        print("if you put", voltage, "volts through it.")
        print("-- Lovely plumage, the", type)
        print("-- It's", state, "!")

accepterar ett obligatoriskt argument (`voltage`) och tre valfria argument (`state`, `action` och `type`). Denna funktion kan anropas på något av följande sätt:

    papegoja(1000) # 1 positionellt argument
    parrot(voltage=1000) # 1 nyckelordsargument
    parrot(voltage=1000000, action='VOOOOOM') # 2 nyckelordsargument
    parrot(action='VOOOOOM', voltage=1000000) # 2 nyckelordsargument
    papegoja('en miljon', 'berövad livet', 'hoppa') # 3 positionella argument
    papegoja('tusen', tillstånd='skjuter upp prästkragarna') # 1 positionellt, 1 nyckelord

men alla följande anrop skulle vara ogiltiga:

    parrot() # nödvändigt argument saknas
    parrot(voltage=5.0, 'dead') # icke-nyckelordsargument efter ett nyckelordsargument
    parrot(110, voltage=220) # duplicerat värde för samma argument
    parrot(skådespelare='John Cleese') # okänt nyckelordsargument

I ett funktionsanrop måste nyckelordsargument följa efter positionsargument. Alla nyckelordsargument som skickas måste matcha ett av de argument som accepteras av funktionen (t.ex. `actor` är inte ett giltigt argument för funktionen `parrot`), och deras ordning är inte viktig. Detta inkluderar även icke valfria argument (t.ex. `parrot(voltage=1000)` är också giltigt). Inget argument får ta emot ett värde mer än en gång. Här är ett exempel som misslyckas på grund av denna begränsning:

    >>> def function(a):
    ...     pass
    ...
    >>> function(0, a=0)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: function() got multiple values for argument 'a'

När en slutlig formell parameter av formen `**name` finns, får den en dictionary (se Mapping types — dict, frozendict) som innehåller alla nyckelordsargument utom de som motsvarar en formell parameter. Detta kan kombineras med en formell parameter av formen `*name` (beskrivs i nästa underavsnitt) som tar emot en tuple som innehåller de positionella argumenten utöver den formella parameterlistan. (`*name` måste förekomma före `**name`.) Om vi t.ex. definierar en funktion så här:

    def cheeseshop(kind, *arguments, **keywords):
        print("-- Do you have any", kind, "?")
        print("-- I'm sorry, we're all out of", kind)
        for arg in arguments:
            print(arg)
        print("-" * 40)
        for kw in keywords:
            print(kw, ":", keywords[kw])

Det skulle kunna kallas så här:

    cheeseshop("Limburger","Den är väldigt rinnig, sir.",
               "Den är verkligen mycket, MYCKET rinnig, sir.",
               butiksinnehavare="Michael Palin",
               kund="John Cleese",
               sketch="Sketch från ostbutiken")

och naturligtvis skulle det tryckas:

    -- Har ni någon Limburger?
    -- Jag är ledsen, vi har slut på Limburger
    Den är väldigt rinnig, sir.
    Den är verkligen mycket, MYCKET rinnande, sir.
    ----------------------------------------
    butiksinnehavare : Michael Palin
    kund : John Cleese
    sketch : Ostbutiken

Observera att den ordning i vilken nyckelordsargumenten skrivs ut garanterat kommer att överensstämma med den ordning i vilken de angavs i funktionsanropet.

### 4.9.3. Särskilda parametrar

Som standard kan argument skickas till en Python-funktion antingen genom position eller uttryckligen genom nyckelord. För läsbarhet och prestanda är det vettigt att begränsa hur argument kan skickas så att en utvecklare bara behöver titta på funktionsdefinitionen för att avgöra om objekt skickas med position, med position eller nyckelord eller med nyckelord.

En funktionsdefinition kan se ut på följande sätt:

    def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
          -----------    ----------     ----------
            |             |                  |
            |        Positional or keyword   |
            |                                - Keyword only
             -- Positional only

där `/` och `*` är valfria. Om dessa symboler används anger de vilken typ av parameter som argumenten kan skickas till funktionen med: endast positionell, positionell-eller-nyckelord och endast nyckelord. Nyckelordsparametrar kallas också namngivna parametrar.

#### 4.9.3.1. Positionerings- eller nyckelordsargument

Om `/` och `*` inte finns med i funktionsdefinitionen kan argument skickas till en funktion genom position eller nyckelord.

#### 4.9.3.2. Endast positionella parametrar

Om man tittar på detta lite mer i detalj är det möjligt att markera vissa parametrar som positional-only. Om positional-only, spelar parametrarnas ordning roll, och parametrarna kan inte skickas med nyckelord. Positional-only-parametrar placeras före ett `/` (framåtriktat snedstreck). `/` används för att logiskt separera parametrar som endast är positionella från resten av parametrarna. Om det inte finns någon `/` i funktionsdefinitionen, finns det inga enbart positionella parametrar.

Parametrar efter `/` kan vara positionella-eller-nyckelord eller endast nyckelord.

#### 4.9.3.3. Argument som endast innehåller nyckelord

För att markera parametrar som keyword-only, vilket indikerar att parametrarna måste skickas med nyckelordsargument, placera en `*` i argumentlistan precis före den första keyword-only-parametern.

#### 4.9.3.4. Funktion Exempel

Tänk på följande exempel på funktionsdefinitioner och var uppmärksam på markörerna `/` och `*`:

    >>> def standard_arg(arg):
    ...     print(arg)
    ...
    >>> def pos_only_arg(arg, /):
    ...     print(arg)
    ...
    >>> def kwd_only_arg(*, arg):
    ...     print(arg)
    ...
    >>> def combined_example(pos_only, /, standard, *, kwd_only):
    ...     print(pos_only, standard, kwd_only)

Den första funktionsdefinitionen, `standard_arg`, den mest bekanta formen, lägger inga restriktioner på anropskonventionen och argument kan skickas med position eller nyckelord:

    >>> standard_arg(2)
    2

    >>> standard_arg(arg=2)
    2

Den andra funktionen `pos_only_arg` är begränsad till att endast använda positionella parametrar eftersom det finns en `/` i funktionsdefinitionen:

    >>> pos_only_arg(1)
    1

    >>> pos_only_arg(arg=1)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: 'arg'

Den tredje funktionen `kwd_only_arg` tillåter endast nyckelordsargument som anges med en `*` i funktionsdefinitionen:

    >>> kwd_only_arg(3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given

    >>> kwd_only_arg(arg=3)
    3

Och den sista använder alla tre anropskonventionerna i samma funktionsdefinition:

    >>> combined_example(1, 2, 3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: combined_example() takes 2 positional arguments but 3 were given

    >>> combined_example(1, 2, kwd_only=3)
    1 2 3

    >>> combined_example(1, standard=2, kwd_only=3)
    1 2 3

    >>> combined_example(pos_only=1, standard=2, kwd_only=3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: combined_example() got some positional-only arguments passed as keyword arguments: 'pos_only'

Slutligen, betrakta denna funktionsdefinition som har en potentiell kollision mellan det positionella argumentet `name` och `**kwds` som har `name` som nyckel:

    def foo(name, **kwds):
        return 'name' in kwds

Det finns inget möjligt anrop som får den att returnera `True` eftersom nyckelordet `'name'` alltid kommer att bindas till den första parametern. Till exempel:

    >>> foo(1, **{'name': 2})
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: foo() got multiple values for argument 'name'
    >>>

Men med `/` (endast positionella argument) är det möjligt eftersom det tillåter `namn` som ett positionellt argument och `'namn'` som en nyckel i nyckelordet arguments:

    >>> def foo(name, /, **kwds):
    ...     return 'name' in kwds
    ...
    >>> foo(1, **{'name': 2})
    True

Med andra ord kan namnen på parametrar som endast är positionella användas i `**kwds` utan tvetydighet.

#### 4.9.3.5. Sammanfattning

Användningsfallet avgör vilka parametrar som ska användas i funktionsdefinitionen:

    def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):

Som vägledning:

- Använd positional-only om du vill att namnet på parametrarna inte ska vara tillgängligt för användaren. Detta är användbart när parameternamn inte har någon verklig betydelse, om du vill tvinga fram ordningen på argumenten när funktionen anropas eller om du behöver ta några positionella parametrar och godtyckliga nyckelord.

- Använd endast nyckelord när namnen har betydelse och funktionsdefinitionen blir mer begriplig genom att vara explicit med namn eller om du vill förhindra att användare förlitar sig på positionen för det argument som skickas.

- För ett API, använd endast positionell för att förhindra att API-ändringar bryts om parameterns namn ändras i framtiden.

### 4.9.4. Listor med godtyckliga argument

Slutligen, det minst använda alternativet, är att ange att en funktion kan anropas med ett godtyckligt antal argument. Dessa argument kommer att paketeras i en tupel (se Tupler och sekvenser). Före det variabla antalet argument kan noll eller fler normala argument förekomma.

    def write_multiple_items(file, separator, *args):
        file.write(separator.join(args))

Normalt kommer dessa variadiska argument sist i listan över formella parametrar, eftersom de samlar upp alla återstående inmatningsargument som skickas till funktionen. Alla formella parametrar som förekommer efter parametern `*args` är ”keyword-only”-argument, vilket innebär att de endast kan användas som nyckelord och inte som positionsargument.

    >>> def concat(*args, sep="/"):
    ...     return sep.join(args)
    ...
    >>> concat("earth", "mars", "venus")
    'earth/mars/venus'
    >>> concat("earth", "mars", "venus", sep=".")
    'earth.mars.venus'

### 4.9.5. Uppackning av argumentlistor

Den omvända situationen uppstår när argumenten redan finns i en lista eller tupel men måste packas upp för ett funktionsanrop som kräver separata positionsargument. Till exempel förväntar sig den inbyggda funktionen `range()` separata start- och stop-argument. Om de inte finns tillgängliga separat, skriv funktionsanropet med `*` -operatorn för att packa upp argumenten ur en lista eller tupel:

    >>> list(range(3, 6))            # normal call with separate arguments
    [3, 4, 5]
    >>> args = [3, 6]
    >>> list(range(*args))            # call with arguments unpacked from a list
    [3, 4, 5]

På samma sätt kan ordböcker leverera nyckelordsargument med `**` -operatorn:

    >>> def parrot(voltage, state='a stiff', action='voom'):
    ...     print("-- This parrot wouldn't", action, end=' ')
    ...     print("if you put", voltage, "volts through it.", end=' ')
    ...     print("E's", state, "!")
    ...
    >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
    >>> parrot(**d)
    -- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

### 4.9.6. Lambda-uttryck

Små anonyma funktioner kan skapas med nyckelordet `lambda`. Denna funktion returnerar summan av sina två argument: `lambda a, b: a+b`. Lambda-funktioner kan användas överallt där funktionsobjekt krävs. De är syntaktiskt begränsade till ett enda uttryck. Semantiskt sett är de bara syntaktiskt socker för en normal funktionsdefinition. Precis som nästlade funktionsdefinitioner kan lambdafunktioner referera till variabler från det scope som innehåller dem:

    >>> def make_incrementor(n):
    ...     return lambda x: x + n
    ...
    >>> f = make_incrementor(42)
    >>> f(0)
    42
    >>> f(1)
    43

I exemplet ovan används ett lambda-uttryck för att returnera en funktion. En annan användning är att skicka en liten funktion som ett argument. Till exempel tar `list.sort()` en sorteringsnyckelfunktion key som kan vara en lambda-funktion:

    >>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
    >>> pairs.sort(key=lambda pair: pair[1])
    >>> pairs
    [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

### 4.9.7. Dokumentation Strängar

Här följer några konventioner om innehåll och formatering av dokumentationssträngar.

Den första raden bör alltid vara en kort och koncis sammanfattning av objektets syfte. För korthetens skull bör inte objektets namn eller typ anges explicit, eftersom dessa finns tillgängliga på annat sätt (utom om namnet råkar vara ett verb som beskriver en funktions funktion). Denna rad ska inledas med en versal och avslutas med en punkt.

Om det finns fler rader i dokumentationssträngen bör den andra raden vara tom, så att sammanfattningen visuellt skiljs från resten av beskrivningen. De följande raderna bör vara ett eller flera stycken som beskriver objektets anropskonventioner, dess bieffekter etc.

The Python parser strips indentation from multi-line string literals when they serve as module, class, or function docstrings.

Här är ett exempel på en dokumentsträng med flera rader:

    >>> def my_function():
    ...     """Do nothing, but document it.
    ...
    ...     No, really, it doesn't do anything:
    ...
    ...         >>> my_function()
    ...         >>>
    ...     """
    ...     pass
    ...
    >>> print(my_function.__doc__)
    Do nothing, but document it.

    No, really, it doesn't do anything:

        >>> my_function()
        >>>

### 4.9.8. Funktionskommentarer

Function annotations är helt valfri metadatainformation om de typer som används av användardefinierade funktioner (se PEP 3107 och PEP 484 för mer information).

Annotationer lagras i attributet `__annotations__` i funktionen som en ordbok och har ingen effekt på någon annan del av funktionen. Parameterannoteringar definieras av ett kolon efter parameternamnet, följt av ett uttryck som utvärderas till värdet på annoteringen. Returannoteringar definieras av en bokstavlig `-&gt;`, följt av ett uttryck, mellan parameterlistan och kolon som anger slutet på `def`-satsen. Följande exempel har ett obligatoriskt argument, ett valfritt argument och returvärdet annoterat:

    >>> def f(ham: str, eggs: str = 'eggs') -> str:
    ...     print("Annotations:", f.__annotations__)
    ...     print("Arguments:", ham, eggs)
    ...     return ham + ' and ' + eggs
    ...
    >>> f('spam')
    Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
    Arguments: spam eggs
    'spam and eggs'

## 4.10. Intermezzo: Kodningsstil

Now that you are about to write longer, more complex pieces of Python, it is a good time to talk about coding style. Most languages can be written (or more concisely, formatted) in different styles; some are more readable than others. Making it easy for others to read your code is always a good idea, and adopting a nice coding style helps tremendously for that.

För Python har PEP 8 vuxit fram som den stilguide som de flesta projekt följer; den främjar en mycket läsbar och tilltalande kodningsstil. Varje Python-utvecklare bör läsa den vid något tillfälle; här är de viktigaste punkterna extraherade för dig:

- Använd 4 spaltmeters indrag och inga tabbar.

  4 mellanslag är en bra kompromiss mellan litet indrag (ger större häckningsdjup) och stort indrag (lättare att läsa). Tabbar skapar förvirring och är bäst att utesluta.

- Radbryt raderna så att de inte överstiger 79 tecken.

  Detta underlättar för användare med små skärmar och gör det möjligt att ha flera kodfiler sida vid sida på större skärmar.

- Använd tomma rader för att separera funktioner och klasser, och större kodblock inuti funktioner.

- När det är möjligt, placera kommentarer på en egen rad.

- Använd docstrings.

- Använd mellanslag runt operatorer och efter kommatecken, men inte direkt inuti parenteser: `a = f(1, 2) + g(3, 4)`.

- Namnge dina klasser och funktioner på ett konsekvent sätt; konventionen är att använda `UpperCamelCase` för klasser och `lowercase_with_underscores` för funktioner och metoder. Använd alltid `self` som namn på det första metodargumentet (se En första titt på klasserna för mer information om klasser och metoder).

- Använd inte avancerade kodningar om din kod är avsedd att användas i internationella miljöer. Pythons standard, UTF-8, eller till och med vanlig ASCII fungerar bäst i alla fall.

- Använd inte heller icke-ASCII-tecken i identifierare om det bara finns en liten risk för att personer som talar ett annat språk kommer att läsa eller underhålla koden.

Fotnoter

[1]

Egentligen skulle anrop genom objektreferens vara en bättre beskrivning, eftersom om ett föränderligt objekt skickas kommer den som anropar att se alla ändringar som den som anropar gör på det (objekt som infogas i en lista).