Effektiv felsökning med Python Assert Statement

By rik

Att använda påståenden för effektiv felsökning i Python

Är du programmerare? I så fall är förmågan att felsöka ett måste, oavsett vilket språk du använder. Denna artikel går igenom hur du kan använda påståenden (`assert`) i Python för att förbättra din felsökningsprocess.

När du bygger ett projekt kommer du ofta att skapa flera moduler, inklusive funktioner, klasser och mer. Det är vanligt att stöta på oväntade resultat eller fel på grund av buggar i koden. Påståenden är otroligt användbara vid felsökning av sådana problem.

I den här guiden kommer vi att titta på hur påståenden fungerar i Python, följt av några kodexempel för att visa hur de kan användas. Vi kommer också att gå igenom vad ett ”AssertionError” är och hur du kan använda det för att identifiera och åtgärda problem i din kod under utvecklingsprocessen.

Låt oss börja!

Använda `assert` i Python: En djupdykning

Vi börjar med syntaxen för påståenden och fortsätter sedan med exempelkod för att se funktionen i praktiken.

Syntaxen för `assert`

Här är hur du använder `assert`-satsen i Python:

assert uttryck, meddelande

Här betyder:

  • uttryck: Ett valfritt Python-uttryck som utvärderas. Det kan vara ett villkor för en variabel, ett sanningsvärde eller returvärdet från en funktion.
  • Om uttryck är True så gör `assert`-satsen ingenting. Programmet fortsätter som vanligt.
  • Om uttryck är False så genereras ett `AssertionError`-undantag.
  • meddelande: En valfri sträng som visas som en del av spårutskriften om ett `AssertionError`-undantag inträffar.

Nu ska vi titta på några exempel för att se hur `assert` kan hjälpa oss att skriva renare kod med färre buggar.

Du kan hitta koden som används i den här guiden på GitHub.

Exempel på påståenden i Python

Låt oss titta på ett scenario där du har en variabel för rabatt i din kod. Du vill säkerställa att rabattvärdet aldrig överskrider ett maxvärde.

För att undvika att du av misstag sätter rabatten till ett för högt värde kan du använda ett påstående. Uttrycket att utvärdera är: rabatt <= max_rabatt.

>>> max_rabatt = 50
>>> rabatt = 20
>>> assert rabatt <= max_rabatt

Eftersom rabatten (20) är lägre än maxrabatten (50) så returnerar `assert`-satsen ingenting.

`AssertionError`-undantag

Om rabatten är större än maxrabatten genereras ett `AssertionError`-undantag.

>>> rabatt = 75
>>> assert rabatt <= max_rabatt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

Som vi nämnt kan vi också ge ett meddelande till `assert`-satsen.

Låt oss lägga till ett meddelande som ger mer information. Vi använder en Python f-sträng för att inkludera både rabatt och maxrabatt i utskriften.

>>> assert rabatt <= max_rabatt, f"Rabatten bör vara högst {max_rabatt}; fick rabatt = {rabatt}"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: Rabatten bör vara högst 50; fick rabatt = 75

Som du kan se, innehåller `AssertionError`-undantaget nu de värdena för rabatt och maxrabatt.

Felsökning och testning med påståenden

När du skapar funktioner kan det hända att buggar dyker upp som gör att funktionen inte gör det den ska.

Låt oss säga att du har en funktion som beräknar slutpoäng för ett prov. Om en student tar en bonusfråga får hen 10 poäng extra. 😄

Här är funktionen get_final_score:

  • Den tar en poäng, score, och en boolesk variabel, bonus.
  • Om bonus är True får studenten 10 extra poäng.
  • Funktionen returnerar slutresultatet.
def get_final_score(score, bonus):
    if bonus:
        score += 10
    return score

Låt oss testa funktionen. Med poäng 34 och 40, och bonus True respektive False, får vi slutresultat 44 och 40.

print(get_final_score(34,True))
# 44
print(get_final_score(40,False))
# 40

Antag att maxpoängen på provet är 50. Om en student har 49 poäng och tar bonusfrågan får hen 59 poäng enligt funktionen.

print(get_final_score(49,True))
# 59

Tekniskt sett stämmer det. Men antag att en student inte kan få mer poäng än det maximala möjliga. 🙂

Låt oss initialisera en variabel max_score och fånga resultatet av funktionen i final_score.

Sedan lägger vi till ett påstående som kollar om final_score är lägre än max_score.

def get_final_score(score,bonus):
    if bonus:
        score += 10
    return score

final_score = get_final_score(47,True)
max_score = 50

assert final_score <= max_score

Vi får nu ett `AssertionError`-undantag för funktionsanropet get_final_score(47,True):

Traceback (most recent call last):
  File "main.py", line 17, in <module>
    assert final_score <= max_score
AssertionError

Nu lägger vi till en beskrivande f-sträng till påståendet:

assert final_score <= max_score,f"Slutpoängen bör vara högst {max_score}; fick {final_score}"
Traceback (most recent call last):
  File "main.py", line 17, in <module>
    assert final_score <= max_score,f"Slutpoängen bör vara högst {max_score}; fick {final_score}"
AssertionError: Slutpoängen bör vara högst 50; fick 57

Ändra funktionen

Låt oss ändra funktionen get_final_score för att åtgärda det oväntade resultatet:

  • Funktionen tar även max_score som en parameter.
  • Vi kollar om bonus är True. Om så är fallet, lägger vi till 10 poäng till score.
  • Sedan kollar vi om score är högre än max_score. Om så är fallet returnerar vi max_score.
  • Annars returnerar vi score.

Nu har vi säkerställt att slutpoängen alltid är mindre än eller lika med max_score.

def get_final_score(score,bonus,max_score):
    if bonus:
        score += 10
    if score > max_score:
        return max_score
    return score

Testa funktionen genom att lägga till några `assert`-satser för att bekräfta att funktionen fungerar som den ska.

Viktigt om `AssertionError`

Även om ett `AssertionError`-undantag inträffar när ett uttryck är False, ska vi inte hantera det som ett vanligt undantag.

try:
    <doing this>
except AssertionError:
    <do this>

I exemplet med get_final_score använde vi påståenden för att kontrollera att final_score är lägre än max_score. Sedan ändrade vi funktionen för att undvika att påståendet misslyckas.

Det är så påståenden är avsedda att användas. De är som ”sanity checks” i koden och hjälper till att skriva renare kod. Undantagshantering å andra sidan är till för att förutse och hantera oväntade fel som kan inträffa under körningen, som ogiltiga värden.

Sammanfattningsvis, använd `assert` för effektiv felsökning och hantera inte `AssertionError` som ett undantag.

Slutsats

Den här artikeln har förklarat hur du använder `assert`-satsen i Python. Här är en sammanfattning:

  • Påståenden har formen `assert uttryck`. Det kontrollerar om uttrycket är True. Om det inte är det genereras ett `AssertionError`-undantag.
  • Du kan även använda `assert uttryck, meddelande`. Meddelandet skrivs ut om ett `AssertionError`-undantag inträffar.
  • Undvik att använda undantagshantering för `AssertionError`. Använd påståenden som ett felsökningsverktyg för att kontrollera att din kod beter sig som förväntat.

Som utvecklare är påståenden ett viktigt felsökningsverktyg. För att säkerställa att varje modul i ditt projekt fungerar som det ska, kan du lära dig att skriva enhetstester i Python.

Kolla också in den här listan över Python-projekt för nybörjare som du kan arbeta med.