Slik bruker du *args og **kwargs i Python

Lær *args og **kwargs i Python. Send et vilkårlig antall argumenter til funksjoner.

Videoforhåndsvisning

Opprett konto for å se video

Det er helt gratis og tar under 30 sekunder

Opprett gratis kontoHar du konto? Logg inn

Du har en funksjon som legger sammen to tall. Fungerer fint. Men hva når du trenger å legge sammen tre? Eller ti? Du kan ikke lage en ny funksjon for hvert antall. Med *args og **kwargs i Python slipper du å bestemme antall parametere på forhånd. Funksjonen tar imot så mange verdier du sender inn.

Slik fungerer *args i Python

Stjerna foran parameternavnet gjør at Python samler alle posisjonsargumenter i en tuple:

def summer(*tall):
    resultat = 0
    for t in tall:
        resultat += t
    return resultat

print(summer(1, 2, 3))         # 6
print(summer(5, 10, 15, 20, 25)) # 75

Navnet "args" er bare en konvensjon. Skriv gjerne *tall, *verdier, eller hva som helst. Det er stjerna som gir funksjonaliteten. Python pakker alle verdiene du sender inn i en tuple, og du kan iterere over den med en for-løkke, akkurat som over en vanlig liste.

Sender du ingen argumenter, blir tupelen tom. Funksjonen krasjer ikke, men du får 0 tilbake fra eksempelet over. Det er god oppførsel.

Forskjellen fra en liste som parameter

Et alternativ er å sende inn en liste:

def summer_liste(tall_liste):
    return sum(tall_liste)

summer_liste([1, 2, 3])  # Må pakke inn i en liste

Med *args slipper du hakeparentesene:

summer(1, 2, 3)  # Sender tallene direkte

Forskjellen er brukervennlighet. *args gir et renere kall, spesielt når du ikke allerede har verdiene i en liste. Har du en eksisterende liste, kan du pakke den ut med stjerne: summer(*min_liste).

Slik fungerer **kwargs

Dobbel stjerne samler nøkkelordargumenter i en dictionary:

def vis_info(**info):
    for nokkel, verdi in info.items():
        print(f"{nokkel}: {verdi}")

vis_info(navn="Anna", alder=30, by="Oslo")

Resultatet blir:

navn: Anna
alder: 30
by: Oslo

Igjen er "kwargs" bare en konvensjon. Du kan kalle parameteren **data eller **innstillinger. Det er dobbelt-stjerna som gjør at Python samler nøkkelord-verdi-parene i en dictionary.

**kwargs er spesielt nyttig når du bygger funksjoner som tar imot innstillinger. I stedet for å definere ti valgfrie parametere med standardverdier, lar du brukeren sende inn kun det de trenger. Alt annet ignoreres eller får en standard.

Kombiner vanlige parametere med *args og **kwargs

Alle tre typene kan kombineres, men rekkefølgen er fast:

def bestilling(kunde, *produkter, **detaljer):
    print(f"Kunde: {kunde}")
    print(f"Produkter: {produkter}")
    print(f"Detaljer: {detaljer}")

bestilling("Erik", "Laptop", "Mus", frakt="Express", rabatt=10)

Resultatet:

Kunde: Erik
Produkter: ('Laptop', 'Mus')
Detaljer: {'frakt': 'Express', 'rabatt': 10}

Rekkefølgen er alltid: vanlige parametere, deretter *args, deretter **kwargs. Bytter du om, gir Python en SyntaxError. Denne rekkefølgen er logisk: først de obligatoriske verdiene, så de ekstra posisjonelle, og til slutt de navngitte tilleggsverdiene.

Pakk ut med stjerner

Utpakking med * og ** fungerer også den andre veien. Har du en liste eller dictionary, kan du pakke dem ut som argumenter til en funksjon:

def hils(fornavn, etternavn, alder):
    print(f"Hei, {fornavn} {etternavn}. Du er {alder} år.")

person = {"fornavn": "Kari", "etternavn": "Hansen", "alder": 28}
hils(**person)  # Hei, Kari Hansen. Du er 28 år.

Nøklene i dictionaryen må matche parameternavnene i funksjonen. Mangler en nøkkel, får du en TypeError. Har du en ekstra nøkkel som ikke matcher, får du også en TypeError. Det gir deg trygghet: Python sjekker at alt stemmer.

For lister bruker du én stjerne:

tall = [10, 20, 30]
print(*tall)  # 10 20 30 (tre separate argumenter)

Praktisk bruk av args og kwargs

Den vanligste bruken er i dekoratorer og wrapper-funksjoner, der du ikke vet hvilke argumenter den indre funksjonen tar:

def logg_kall(funksjon):
    def wrapper(*args, **kwargs):
        print(f"Kaller {funksjon.__name__}")
        return funksjon(*args, **kwargs)
    return wrapper

Wrapper-funksjonen videreformidler alle argumenter til den opprinnelige funksjonen uten å vite hva de er. Denne teknikken brukes i de fleste Python-rammeverk. Du trenger ikke forstå dekoratorer i detalj ennå, men det er nyttig å gjenkjenne mønsteret når du ser det i andres kode.

En annen vanlig bruk er funksjoner som bygger konfigurasjoner. Du sender inn kun de feltene du vil overstyre, og resten beholder standardverdier:

def opprett_bruker(navn, **ekstra):
    bruker = {"navn": navn, "rolle": "bruker"}
    bruker.update(ekstra)
    return bruker

print(opprett_bruker("Anna", rolle="admin", avdeling="IT"))

Tre feil å unngå med args og kwargs

Feil rekkefølge i parameterlisten. Skriver du def f(**kwargs, *args), får du en SyntaxError. *args må alltid komme før **kwargs.

Bruker *args når du trenger navngitte verdier. Hvis rekkefølgen på verdiene betyr noe (som bredde og høyde), er vanlige parametere tryggere enn *args. Navngitte parametere dokumenterer seg selv.

Fanger alt med **kwargs uten validering. Når du aksepterer hva som helst, risikerer du skrivefeil i nøkkelnavnene som aldri blir oppdaget. Legg inn sjekker for forventede nøkler når det er viktig.

En enkel validering kan se slik ut:

def innstillinger(**kwargs):
    gyldige = {"farge", "storrelse", "skrift"}
    for nokkel in kwargs:
        if nokkel not in gyldige:
            raise TypeError(f"Ukjent innstilling: {nokkel}")

Med denne sjekken oppdager du skrivefeil umiddelbart i stedet for å lure på hvorfor innstillingen ikke tok effekt.

Neste steg

Nå som du kan bruke *args og **kwargs i Python, har du full fleksibilitet i funksjonsdesign. Vil du skrive korte, anonyme funksjoner, viser lambda-funksjoner deg hvordan. Trenger du å håndtere feil i funksjonene dine, er try og except det riktige verktøyet. Du finner også flere eksempler på avansert funksjonsbruk i Python-dokumentasjonen.

Denne videoen er hentet fra kurset Python for nybegynnere på Utdannet.no. I det fulle kurset lærer du også datastrukturer, objektorientert programmering og hvordan du strukturerer større prosjekter.