Løs vanlige Python-feil: Den komplette guiden

Vanlige Feil i Python og Hvordan Løse Dem

Som utvikler er det uunngåelig å støte på feil under programmering. Disse feilene kan variere fra logiske feil som fører til uventede resultater, til brudd på programmeringsspråkets regler, eller feil som oppstår under kjøring av programmet. Slike feil kalles ofte for «bugs».

Uansett hvor enkelt et programmeringsspråk er, er «bugs» en vanlig utfordring. Dette gjelder også for Python.

Selv om Python er kjent for sin lesbarhet og uttrykksfulle syntaks, og anses som relativt enkelt å lære, er du likevel ikke immun mot programmeringsfeil når du bruker dette språket.

Siden feil er en uunngåelig del av programmeringsprosessen, er det en fornuftig strategi å lære om de ulike typene feil som kan oppstå og hvorfor de oppstår. Dette vil hjelpe deg med å unngå eller minimere feil mens du programmerer, og vite hvordan du skal håndtere dem når de oppstår.

Her er noen vanlige Python-feil du kan støte på:

Syntaksfeil

En syntaksfeil oppstår når koden du skriver bryter reglene for programmeringsspråket. Dette resulterer i en ugyldig kodelinje.

For eksempel, i Python, må strenger settes innenfor anførselstegn. Hvis du glemmer dette, vil det føre til en syntaksfeil.

Andre syntaksfeil kan oppstå hvis du mangler åpne eller lukkede parenteser, klammer eller krøllparenteser, feilstaver nøkkelord eller funksjonsnavn, glemmer kolon på slutten av kontrollsetninger, eller mangler nødvendige operatorer i uttrykk.

Kort sagt, syntaksfeil oppstår når du bryter en av reglene for hvordan Python-kode skal skrives.

    ## Syntaksfeil på grunn av manglende anførselstegn
    ## rundt strengen som skrives ut
    print("Hello World)
    
    age = 20
    ## Syntaksfeil på grunn av manglende kolon i en if-setning
    if age > 18
        print("Age is over 18")
    
    ## Syntaksfeil fordi '(' aldri ble lukket
    def square(x:
        return x * x
    print(square(4))
  

Når du kjører koden over, får du en feilmelding som ligner:

    File "/home/madici/Desktop/helloworld.py", line 1
        print("Hello World)
              ^
    SyntaxError: unterminated string literal (detected at line 1)
  

For å løse disse feilene, sørg for å bruke korrekt Python-syntaks:

    print("Hello World")
    
    age = 20
    if age > 18:
        print("Age is over 18")
    
    def square(x):
        return x * x
    print(square(4))
  

Innrykksfeil

I motsetning til språk som Java, C eller C++, som bruker krøllparenteser for å definere kodeblokker, bruker Python innrykk for å bestemme strukturen. For eksempel, i Java er all kode som skal kjøres innenfor krøllparentesene til en betingelse.

I Python defineres en kodeblokk gjennom innrykk. Vanligvis er et innrykk på fire mellomrom eller en tabulator, men antall mellomrom er ikke avgjørende så lenge det er konsekvent gjennom hele koden.

Som Python-programmerer vil du sannsynligvis støte på innrykksfeil når du glemmer å legge til nødvendig innrykk i for eksempel kontrollsetninger eller funksjoner, når du bruker både tabulatorer og mellomrom for innrykk (noe som forvirrer tolkeren), eller når innrykk ikke er konsistente i hele koden.

Her er et eksempel på kode som resulterer i en innrykksfeil:

    age = 20
    if age > 18:
    print("Age is greater than 18")
       print("You're allowed to drive")
    else:
        print("Age is less than 18")
  

Feilmeldingen fra koden over vises nedenfor:

    File "/home/madici/Desktop/helloworld.py", line 3
        print("Age is greater than 18")
        ^
    IndentationError: expected an indented block after 'if' statement on line 2
  

For å korrigere feilen, må du sørge for at linjen etter if-setningen er rykket inn og at alle innrykk er konsistente:

    age = 20
    if age > 18:
       print("Age is greater than 18")
       print("You're allowed to drive")
    else:
       print("Age is less than 18")
  

TypeError

I Python oppstår en TypeError når du prøver å utføre en operasjon med inkompatible datatyper. For eksempel, hvis du prøver å legge sammen en streng og et tall eller sette sammen en streng med et tall, vil dette gi en TypeError.

Du kan også oppleve TypeErrors når du bruker funksjoner eller metoder med feil datatyper, når du prøver å bruke en ikke-heltallsindeks for å få tilgang til elementer i en liste, eller når du prøver å iterere gjennom et objekt som ikke er itererbart.

Generelt vil enhver operasjon som bruker feil datatyper føre til en TypeError.

Her er noen eksempler på operasjoner som kan føre til TypeErrors:

    # TypeError på grunn av sammenkobling av en streng og et tall
    age = 25
    message = "Jeg er " + age + " år gammel."

    list1 = [1, "hei", 5, "verden", 18, 2021]
    # TypeError på grunn av feil bruk av innebygde metoder
    print(sum(list1))

    # TypeError på grunn av addisjon av en streng og et tall
    num1 = 10
    num2 = "16"
    print(num1 + num2)

    # TypeError på grunn av bruk av en ikke-heltallsindeks
    list2 = ["hei", "fra", "den", "andre", "siden"]
    print(list2["1"])
  

Feilmeldingene fra koden over vises nedenfor:

    File "/home/madici/Desktop/helloworld.py", line 3, in <module>
        message = "Jeg er " + age + " år gammel."
                  ~~~~~~~~^~~~~
    TypeError: can only concatenate str (not "int") to str
  

For å fjerne disse feilene, bruk korrekte datatyper eller typekonverteringer:

    age = 25
    message = "Jeg er " + str(age) + " år gammel."
    
    list1 = [1, 5, 18, 2021]
    print(sum(list1))

    num1 = 10
    num2 = "16"
    print(num1 + int(num2))
    
    list2 = ["hei", "fra", "den", "andre", "siden"]
    print(list2[1])
  

AttributeError

En AttributeError oppstår når du prøver å bruke et attributt eller kalle en metode som ikke eksisterer på objektet. En slik feil indikerer at et objekt mangler et attributt eller en metode som blir kalt.

For eksempel vil det gi en AttributeError hvis du kaller en strengmetode på et tall, fordi metoden ikke finnes for den objekttypen.

I eksemplet under blir metoden `capitalize()`, som brukes for å konvertere den første bokstaven i en streng til stor bokstav, forsøkt brukt på et heltall. Dette resulterer i en AttributeError fordi int-objekter ikke har en `capitalize()`-metode.

    # AttributeError på grunn av kall av capitalize() på en int-verdi
    num = 1445
    cap = num.capitalize()
    print(cap)
  

Kjøring av denne koden resulterer i feilmeldingen:

    File "/home/madici/Desktop/helloworld.py", line 3, in <module>
        cap = num.capitalize()
              ^^^^^^^^^^^^^^
    AttributeError: 'int' object has no attribute 'capitalize'
  

For å løse en AttributeError, må du sørge for at metoden eller attributtet du kaller faktisk finnes på den objekttypen du bruker. I dette tilfellet kan du løse problemet ved å kalle `capitalize()` på en streng:

ImportError

En ImportError oppstår når du prøver å importere en modul som ikke eksisterer eller ikke er tilgjengelig i ditt nåværende miljø. Dette kan skyldes at modulen ikke er installert, at du ikke har konfigurert riktig sti, eller at du har feilstavet modulens navn.

En ImportError har en underklasse som kalles ModuleNotFoundError, som er feilen som oppstår når du prøver å importere en modul som ikke finnes.

Eksempelvis vil koden nedenfor som prøver å importere dataanalysebiblioteket pandas, gi en slik feil fordi modulen ikke er installert ennå.

ImportError-meldingen som genereres vises nedenfor:

    File "/home/madici/Desktop/helloworld.py", line 1, in <module>
        import pandas
    ModuleNotFoundError: No module named 'pandas'
  

For å løse en slik feil, sørg for at modulene du prøver å importere er installert. Hvis det ikke løser feilen, sjekk at du har stavet modulnavnet riktig og at du har lagt inn korrekt filbane for å få tilgang til modulen.

ValueError

En ValueError oppstår når en funksjon mottar en verdi av riktig datatype, men verdien er likevel upassende. For eksempel vil funksjonen `math.sqrt()` returnere en ValueError hvis du gir inn et negativt tall.

Selv om verdien er av riktig type (et tall), er den negativ og dermed ikke gyldig for funksjonen.

Funksjonen `int()` som konverterer et tall eller en streng vil returnere en ValueError hvis du sender inn en streng som ikke er en numerisk streng. Å sende inn «123» eller «45» til funksjonen gir ingen feil, da disse strengene kan konverteres til heltall. Derimot vil en streng som ikke er en numerisk streng, som «Hei», returnere en ValueError. Selv om «Hei» er en streng, er den ikke passende siden den ikke har en heltallsekvivalent.

Her er et eksempel som genererer en ValueError:

    # ValueError som følge av en upassende int-verdi i sqrt()
    import math
    num = -64
    root = math.sqrt(num)
    print(root)
    
    # ValueError som følge av å sende en ikke-numerisk streng til int()
    numString = "Hei"
    num = int(numString)
    print(num)
  

Feilmeldingene som følger av denne koden vises nedenfor:

Feilmeldingen som genereres er som følger:

    File "/home/madici/Desktop/helloworld.py", line 4, in <module>
        root = math.sqrt(num)
              ^^^^^^^^^^^^^^
    ValueError: math domain error
  

For å rette opp feilen, bruk passende verdier i funksjonene:

    import math
    num = 64
    root = math.sqrt(num)
    print(root)

    numString = "5231"
    num = int(numString)
    print(num)
  

IOFeil

IOError (Input/Output Error) er en feil som oppstår når en inngangs- eller utgangsoperasjon feiler. Dette kan skyldes forsøk på å få tilgang til en fil som ikke eksisterer, utilstrekkelig lagringsplass, forsøk på å få tilgang til en fil du ikke har tilgang til eller forsøk på å få tilgang til en fil som brukes av andre prosesser.

Metoder som `open()`, `read()`, `write()` og `close()` som brukes i forbindelse med filer, er vanlige kilder til slike feil.

Tenk på koden nedenfor som prøver å åpne en fil kalt «notater.txt» som ikke finnes. Dette resulterer i en IOError som gir FileNotFoundError:

Med følgende feilmelding:

    File "/home/madici/Desktop/helloworld.py", line 2, in <module>
        file1 = open("notes.txt", "r")
                ^^^^^^^^^^^^^^^^^^^^^^
    FileNotFoundError: [Errno 2] No such file or directory: 'notes.txt'
  

For å unngå denne feilen, må du sørge for at «notater.txt» finnes i katalogen du kjører koden fra. En annen måte å håndtere IOErrors på, er å bruke en `try…except`-blokk:

Navnefeil

NameError er en feil som oppstår når du prøver å bruke en variabel, funksjon eller modul som ikke finnes, ikke er definert i gjeldende omfang, eller som ikke har blitt tildelt en verdi.

En slik feil oppstår vanligvis når du feilstaver variabel- eller funksjonsnavn, eller bruker dem før de er definert. Bruk av en modul uten å importere den vil også resultere i en NameError.

Følgende kode vil resultere i en NameError:

    # NameError fordi math-modulen ikke er importert
    num = 64
    root = math.sqrt(64)
    print(root)

    # NameError fordi x brukes før den er definert
    y = 23
    print(x)

    # NameError fordi funksjonsnavnet ikke er definert
    def greet():
        print("God morgen")
    great() # NameError: name 'great' is not defined
  

Følgende feilmeldinger er et resultat av koden over:

Et eksempel på en NameError vises nedenfor:

    File "/home/madici/Desktop/helloworld.py", line 3, in <module>
        root = math.sqrt(64)
               ^^^^
    NameError: name 'math' is not defined
  

For å løse en slik navnefeil, sørg for at du ikke bruker moduler før du importerer dem, at du ikke bruker variabler eller funksjoner før du definerer dem, og at du ikke staver funksjons- eller variabelnavn feil:

    import math
    num = 64
    root = math.sqrt(64)
    print(root)

    y = 23
    print(y)
    
    def greet():
        print("God morgen")
    greet()
  

Indeksfeil

En IndexError oppstår når du prøver å få tilgang til en indeks i en liste eller tuppel som er utenfor rekkevidde. For eksempel, tenk på listen:

    list1 = [1, 2, 3, 4, 5]
  

Listen har fem elementer. Python teller indekser fra 0. Listen ovenfor har derfor indekser fra 0 til n-1, hvor n er antall elementer i listen. I dette tilfellet vil listen ha indekser fra 0 til 4.

Hvis du prøver å få tilgang til et element med en indeks som er større enn 4, får du en IndexError fordi indeksen er utenfor rekkevidde. Koden nedenfor vil gi en IndexError:

    list1 = [1, 2, 3, 4, 5]
    item = list1[6] # IndexError fordi listeindeksen er utenfor rekkevidde
    print(item)
  

Feilmeldingen som vises nedenfor:

IndexError-meldingen som genereres er som følger:

    File "/home/madici/Desktop/helloworld.py", line 2, in <module>
        item = list1[6] # IndexError fordi listeindeksen er utenfor rekkevidde
               ~~~~~^^^
    IndexError: list index out of range
  

Den beste måten å unngå en IndexError på, er å bruke funksjonene `range()` og `len()` for å sikre at du kun får tilgang til elementer som er innenfor rekkevidde:

    list1 = [1, 2, 3, 4, 5]

    for i in range(len(list1)):
        print(list1[i])
  

KeyError

En KeyError oppstår når du prøver å få tilgang til et element fra en ordbok ved hjelp av en nøkkel, og nøkkelen ikke finnes i ordboken. For eksempel, ta ordboken nedenfor:

    cities = {"Canada": "Ottawa", "USA": "Washington", "Italy": "Rome"}
  

Nøklene i ordboken er «Canada», «USA» og «Italy». Du kan få tilgang til elementene i ordboken ved å bruke disse nøklene. Men hvis du prøver å få tilgang til et element ved hjelp av en nøkkel som ikke eksisterer, for eksempel «Brazil», vil du oppleve en KeyError:

KeyError-meldingen som genereres vises nedenfor:

    File "/home/madici/Desktop/helloworld.py", line 6, in <module>
        print(cities["Brazil"])
              ~~~~~~^^^^^^^^^^
    KeyError: 'Brazil'
  

For å løse en KeyError, må du forsikre deg om at nøklene du bruker for å få tilgang til elementer i en ordbok faktisk finnes i ordboken. Du kan bruke en `if…else`-setning for å sjekke:

    cities = {"Canada": "Ottawa", "USA": "Washington", "Italy": "Rome"}
    
    country = "Canada"
    
    if country in cities:
        print("Hovedstaden i " + country + " er " + cities[country])
    else:
        print("Nøkkelen " + country + " finnes ikke i ordboken.")
  

På denne måten unngår du å støte på KeyErrors når du får tilgang til elementer fra en ordbok.

Konklusjon

Uansett erfaringsnivå vil du uunngåelig støte på feil når du koder i Python. Det er derfor viktig å gjøre deg kjent med de ulike typene feil som er beskrevet i denne artikkelen, slik at du er i stand til å håndtere dem når de oppstår.

Du kan også utforske noen nyttige Python-enlinjere for å forenkle vanlige oppgaver.