Chyby

Každý začátečník, ale i profík, dělá občas chyby. Tady uvidíte, jak se projevují ty nejčastější.

Nedefinované jméno

Co se stane, když místo print napíšu prnit?

>>> prnit("Hello World")
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    prnit("Hello World")
NameError: name 'prnit' is not defined

Pokud zapíšete jméno objektu (funkce, název proměnné, třídy atd.), který neexistuje, dostanete chybovou hlášku podobnou té z příkladu.

Python se vám bude snažit ukázat kde k chybě došlo (to je ten Traceback). Vypisuje postupně názvy souborů a čísla řádků, kde došlo k volání funkcí až k místu, kde došlo k chybě. Protože jsem příkaz spustil z interaktivního šelu, místo názvu souboru je tam jen "<pyshell#0>". Řádka číslo 1 je asi jasná. Co tam dělá ten modul vám bude jasnější, až si probereme moduly.

Chybná syntaxe

>>> print "Hello World"
  File "<stdin>", line 1
    print "Hello World"
                      ^
SyntaxError: invalid syntax
Tento kód je platným kódem v Pythonu verze 2.7 a starší, takže v těchto verzích chybu nevypíše!

Tady je asi také jasné, o co jde. Nedodrželi jste syntaxi Pythonu verze 3, Python tomu nerozumí, tak si stěžuje. Navíc vám stříška na předposledním řádku ukazuje, kde začal být parser pythonu zmatený. Ale bacha, všimněte si, že je Python zmatený trochu pozdě – chyba začíná už za názvem funkce print, kde by měla být levá závorka. Nenechte se pythonem zmást!

IDLE vypíše u této chyby jen SyntaxError: invalid syntax a nepokusí se zobrazit původce chyby. Příklad je z interaktivního režimu, což mimo jiné poznáte podle toho, že File je stdin, tedy standardní input.

Neukončená uvozovka

>>> print ("Hello World)
  File "
<stdin>", line 1
    print ("
Hello World)
                       ^
SyntaxError: EOL while scanning string literal

Chyba vám říká, že parser narazil na konec řádky (EOL = End Of Line). když četl řeťězcový literál (laicky řečeno text v uvozvkách). Stříška vám ukazuje, kam až to dočetl. Pravou závorku ještě považoval za obsah textu, což je pro parser pořád OK. Za ním už je ale konec řádky a ten v pořádku nebyl.

Chybné kódování

Pro příklad uvažujte, že máte soubor pokus.py s následujícím obsahem uložený ve Windows kódování pro střední evropu windows-1252 (a ne v UTF-8, jak Python očekává).

#! /usr/bin/env python3

print("Žluťoučký kůň")

A pak jej spustíte:

C:\Users\Petr>python test.py
  File "test.py", line 3
SyntaxError: Non-UTF-8 code starting with '\x8e' in file test.py on line 3, but
no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Chybu opravíte buď tím, že překódujete soubor do UTF-8, nebo deklarujete kódování cp-1250 (což je windows-1250 :-)).

#! /usr/bin/env python3
# -*- encoding: windows-1250 -*-

print("Žluťoučký kůň")
# -*- encoding: windows-1250 -*- musí být na první nebo druhé řádce.

Dělení nulou

>>> 3/0
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    3/0
ZeroDivisionError: division by zero

Tentokrát došlo k výjimce ZeroDivisionError. Výjimky ještě budeme probírat v některé z dalších kapitol. K výjimkám dochází za běhu programu když se stane něco, co by se stát nemělo (třeba dělit nulou nelze).
Viz příklad Nedefinované jméno, kde došlo k výjimce NameError.

Parser vs interpret

Parser čte zdrojový kód a snaží se ho předpřipravit interpretu (obojí je součásti programu python). Parser očekává kód, který odpovídá syntaxi jazyka Python.

Pokud dojde k chybě během vykonávání (interpretování) kódu, chyba zobrazí tzv. Traceback (mluvil jsem o něm hned v prvním příkladu). Traceback ukazuje nejen kde k chybě došlo, ale který řetězec volání funkcí k chybě vedl (funkce může volat jinou funkci z jiného souboru a ta zase jinou funkci a ta další a další až se zavolá ta, kde dojde k chybě).

Pokud dojde k chybě už během parsování souboru, tak se neukazuje Traceback, protože k žádnému volání funkcí ještě vůbec nedošlo, ale vypíše se jen místo, kde začal být parser zmatený (označené stříškou). Jde o tzv. SyntaxError (což je mimochodem také výjimka, ale o to tu teď nejde).
IDLE bohužel zobrazí jen chybovou hlášku, ale místo zmatení neukáže.

Pokud jste někdy programovali v programovacím jazyce který se překládá, pak určitě znáte rozdíl mezi chybami v době překladu a chybami za běhu programu. Tady je to podobné – chyby během parsování a chyby během interpretace kódu (klidně můžete říkat i za běhu programu).
Komentář Hlášení chyby
Vytvořeno: 11.5.2013
Naposledy upraveno: 29.8.2015
Tato stánka používá ke svému běhu cookies, díky kterým je možné monitorovat, co tu provádíte (ne že bych to bez cookies nezvládl). Také vás tu bude špehovat google analytics. Jestli si myslíte, že je to problém, vypněte si cookies ve vašem prohlížeči, nebo odejděte a už se nevracejte :-). Prohlížením tohoto webu souhlasíte s používáním cookies. Dozvědět se více..