10 συνήθεις τύποι σφαλμάτων Python και πώς να τους επιλύσετε

Ως προγραμματιστής, είναι βέβαιο ότι θα αντιμετωπίσετε σφάλματα κατά την ανάπτυξη λογισμικού. Αυτό μπορεί να κυμαίνεται από σφάλματα στη λογική σας που οδηγούν σε απροσδόκητα αποτελέσματα, σφάλματα που προκύπτουν από παραβίαση των κανόνων μιας γλώσσας προγραμματισμού, έως και σφάλματα που προκύπτουν κατά την εκτέλεση του προγράμματός σας, μεταξύ πολλών άλλων. Αυτά τα σφάλματα αναφέρονται συνήθως ως σφάλματα.
Τα σφάλματα είναι πανταχού παρόντα σε κάθε γλώσσα προγραμματισμού, ανεξάρτητα από το πόσο εύκολο είναι να μάθετε ή να χρησιμοποιήσετε τη γλώσσα.
Στην Python, για παράδειγμα, αν και η γλώσσα δίνει έμφαση στην αναγνωσιμότητα, ακολουθεί μια εκφραστική σύνταξη και θεωρείται σχετικά εύκολη στην εκμάθηση και τη χρήση σε σύγκριση με άλλες γλώσσες προγραμματισμού, εξακολουθείτε να μην είστε απρόσβλητοι σε σφάλματα προγραμματισμού όταν χρησιμοποιείτε Python.
Δεδομένου ότι τα σφάλματα είναι βέβαιο ότι θα προκύψουν, ένας καλός τρόπος για να τα αντιμετωπίσετε είναι να μάθετε για τους διαφορετικούς τύπους σφαλμάτων που μπορούν να προκύψουν και πώς εμφανίζονται. Αυτό σας επιτρέπει να αποφεύγετε ή να ελαχιστοποιείτε αυτά τα σφάλματα κατά τον προγραμματισμό και επίσης να γνωρίζετε πώς να τα χειρίζεστε όταν προκύπτουν.
Ακολουθούν μερικά από τα κοινά σφάλματα Python που μπορεί να συναντήσετε κατά τον προγραμματισμό χρησιμοποιώντας τη γλώσσα:
Πίνακας περιεχομένων
Συντακτικά Σφάλματα
Ένα συντακτικό σφάλμα είναι ένα σφάλμα που προκύπτει όταν γράφετε κώδικα που παραβιάζει τους κανόνες της γλώσσας προγραμματισμού που χρησιμοποιείτε. Αυτό έχει ως αποτέλεσμα μια μη έγκυρη γραμμή κώδικα.
Στην Python, για παράδειγμα, όταν εκτυπώνετε μια συμβολοσειρά, πρέπει να τοποθετείται ανάμεσα σε εισαγωγικά. Αν δεν το κάνετε αυτό έχει ως αποτέλεσμα ένα συντακτικό σφάλμα.
Ένα συντακτικό σφάλμα μπορεί επίσης να προκύψει όταν χάσετε το άνοιγμα ή το κλείσιμο παρενθέσεων, αγκύλες ή σγουρές αγκύλες, ορθογραφικά λάθη λέξεων-κλειδιών ή ονομάτων συναρτήσεων, χάνετε άνω και κάτω τελείες στο τέλος των δηλώσεων ελέγχου ροής ή όταν χάνετε τους απαιτούμενους τελεστές στις εκφράσεις.
Γενικά, θα προκύψουν συντακτικά σφάλματα εάν παραβιάσετε έναν κανόνα σχετικά με τον τρόπο εγγραφής του κώδικα Python.
## syntax error arising from missing quotation mark ## around the string being printed print("Hello World) age = 20 ## Syntax error arising from missing colon in an if statement if age > 18 print("Age is over 18") ## Syntax error because '(' was never closed def square(x: return x * x print(square(4))
Με την εκτέλεση του παραπάνω κώδικα, θα εμφανιστεί ένα μήνυμα σφάλματος όπως φαίνεται παρακάτω:
Το μήνυμα σφάλματος από την εκτέλεση του κώδικα είναι το εξής:
File "/home/madici/Desktop/helloworld.py", line 1 print("Hello World) ^ SyntaxError: unterminated string literal (detected at line 1)
Για να επιλύσετε αυτά τα σφάλματα, χρησιμοποιήστε τη σωστή σύνταξη Python όπως φαίνεται παρακάτω:
print("Hello World") age = 20 if age > 18: print("Age is over 18") def square(x): return x * x print(square(4))
IndentationError
Σε αντίθεση με άλλες γλώσσες όπως η Java, η C ή η C++, που χρησιμοποιούν σγουρά άγκιστρα για να διαχωρίσουν μπλοκ κώδικα, η Python χρησιμοποιεί εσοχή για να ορίσει την ιεραρχία και τη δομή των μπλοκ κώδικα. Για παράδειγμα, όταν γράφετε εντολές ελέγχου σε Java, όλος ο κώδικας που πρέπει να εκτελεστεί μετά την αξιολόγηση της συνθήκης περιέχεται μέσα σε σγουρά άγκιστρα.
Στην Python, ωστόσο, το μπλοκ κώδικα θα έχει εσοχή. Μια τυπική εσοχή στην Python αποτελείται από τέσσερα κενά ή μια καρτέλα. Ωστόσο, ο αριθμός των διαστημάτων δεν έχει σημασία, εφόσον παραμένει συνεπής σε όλο τον κώδικα που γράφεται.
Ως προγραμματιστής Python, είναι πιθανό να αντιμετωπίσετε σφάλματα εσοχής όταν αποτυγχάνετε να προσθέσετε την απαιτούμενη εσοχή, όπως όταν γράφετε εντολές ελέγχου ή συναρτήσεις, όταν χρησιμοποιείτε tab και κενά για να δημιουργήσετε εσοχές καθώς προκαλεί σύγχυση στον διερμηνέα, όταν βάζετε εσοχές σε λάθος μέρος ή όταν οι εσοχές σας δεν είναι συνεπείς σε όλη τη βάση κωδικών σας.
Ένα παράδειγμα κώδικα που οδηγεί σε σφάλμα εσοχής φαίνεται παρακάτω:
age = 20 if age > 18: print("Age is greater than 18") print("You're allowed to drive") else: print("Age is less than 18")
Τα μηνύματα σφάλματος που προκύπτουν από τον παραπάνω κώδικα φαίνονται παρακάτω:
Το μήνυμα σφάλματος από την εκτέλεση του κώδικα είναι το εξής:
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
Για να διορθώσετε τα σφάλματα, απαιτείται εσοχή στη γραμμή μετά τη δήλωση if ως εσοχή και βεβαιωθείτε ότι ταιριάζει με την εσοχή στον υπόλοιπο κώδικα, όπως φαίνεται παρακάτω:
age = 20 if age > 18: print("Age is greater than 18") print("You're allowed to drive") else: print("Age is less than 18")
Τυπογραφικό λάθος
Στην Python, ένα TypeError είναι μια εξαίρεση που προκύπτει όταν προσπαθείτε να εκτελέσετε μια λειτουργία χρησιμοποιώντας έναν μη συμβατό τύπο δεδομένων. Για παράδειγμα, εάν προσπαθήσετε να προσθέσετε μια συμβολοσειρά και έναν ακέραιο ή να συνδέσετε έναν τύπο δεδομένων συμβολοσειράς με έναν ακέραιο, θα αντιμετωπίσετε ένα TypeError.
Μπορείτε επίσης να αντιμετωπίσετε TypeErrors όταν χρησιμοποιείτε συναρτήσεις ή μεθόδους με λανθασμένους τύπους δεδομένων, όταν προσπαθείτε να χρησιμοποιήσετε ένα μη ακέραιο ευρετήριο για πρόσβαση σε στοιχεία σε έναν επαναληπτικό, όπως μια λίστα, ή όταν προσπαθείτε να κάνετε επανάληψη μέσω ενός αντικειμένου που δεν μπορεί να επαναληφθεί.
Γενικά, οποιαδήποτε λειτουργία που χρησιμοποιεί λανθασμένο τύπο δεδομένων θα οδηγήσει σε TypeError.
Παραδείγματα λειτουργιών που μπορούν να οδηγήσουν σε TypeErrors φαίνονται παρακάτω:
# Type Error resulting from concatenating a string an an integer age = 25 message = "I am " + age + " years old." list1 = [1, "hello", 5, "world", 18, 2021] #Type errors resulting from wrong usage of builtin in methods print(sum(list1)) #TypeError resulting from adding a string and an integer num1 = 10 num2 = "16" print(num1 + num2) #TypeError resulting from using a non integer index list2 = ["hello", "from", "the", "other", "side"] print(list2["1"])
Τα μηνύματα σφαλμάτων που προκύπτουν από τον παραπάνω κώδικα φαίνονται παρακάτω:
Ένα δείγμα μηνύματος TypeError από τον κώδικα φαίνεται παρακάτω:
File "/home/madici/Desktop/helloworld.py", line 3, in <module> message = "I am " + age + " years old." ~~~~~~~~^~~~~ TypeError: can only concatenate str (not "int") to str
Για να καταργήσετε τα σφάλματα, χρησιμοποιήστε τους σωστούς τύπους δεδομένων ή μετατροπές τύπων όπως φαίνεται παρακάτω:
age = 25 message = "I am " + str(age) + " years old." list1 = [1, 5, 18, 2021] print(sum(list1)) num1 = 10 num2 = "16" print(num1 + int(num2)) list2 = ["hello", "from", "the", "other", "side"] print(list2[1])
Χαρακτηριστικό Σφάλμα
Στην Python, εμφανίζεται ένα AttributeError όταν προσπαθείτε να χρησιμοποιήσετε ένα χαρακτηριστικό που δεν υπάρχει στο αντικείμενο ή καλείτε μια μέθοδο που δεν υπάρχει στο αντικείμενο στο οποίο καλείται. Ένα AttributeError δείχνει ότι ένα αντικείμενο δεν έχει ένα χαρακτηριστικό ή μια μέθοδο που καλείται σε αυτό.
Για παράδειγμα, εάν καλέσετε μια μέθοδο συμβολοσειράς σε έναν ακέραιο, θα συναντήσετε ένα AttributeError επειδή η μέθοδος δεν υπάρχει στον τύπο του αντικειμένου που την καλείτε.
Στο παράδειγμα που φαίνεται παρακάτω, η μέθοδος capitalize(), η οποία χρησιμοποιείται για τη μετατροπή του πρώτου γράμματος μιας συμβολοσειράς σε κεφαλαία, καλείται σε έναν ακέραιο. Το αποτέλεσμα είναι ένα σφάλμα χαρακτηριστικού επειδή το int δεν έχει τη μέθοδο capitalize().
# AttributeError arising from calling capitalize() on an int value num = 1445 cap = num.capitalize() print(cap)
Η εκτέλεση αυτού του κωδικού έχει ως αποτέλεσμα το μήνυμα σφάλματος που φαίνεται παρακάτω:
Το μήνυμα AttributeError από τον κώδικα είναι το εξής:
File "/home/madici/Desktop/helloworld.py", line 3, in <module> cap = num.capitalize() ^^^^^^^^^^^^^^ AttributeError: 'int' object has no attribute 'capitalize'
Για να επιλύσετε ένα AttributeError, βεβαιωθείτε ότι η μέθοδος ή το χαρακτηριστικό που καλείτε υπάρχει στον τύπο του αντικειμένου που το καλείτε. Σε αυτήν την περίπτωση, η κλήση της capitalize() σε έναν τύπο δεδομένων συμβολοσειράς επιλύει αυτό το σφάλμα όπως φαίνεται παρακάτω:
Εισαγωγή Σφάλμα
Το ImportError στην Python εμφανίζεται όταν προσπαθείτε να εισαγάγετε μια λειτουργική μονάδα που δεν μπορεί να βρεθεί ή δεν είναι προσβάσιμη στο τρέχον περιβάλλον σας. Μπορεί να μην έχει εγκατασταθεί ακόμα, να μην έχετε διαμορφώσει σωστά τη διαδρομή του ή να έχετε γράψει λάθος τη λειτουργική μονάδα που προσπαθείτε να εγκαταστήσετε.
Ένα ImportError έχει μια ενιαία θυγατρική υποκλάση που ονομάζεται ModuleNotFoundError, το οποίο είναι το σφάλμα που εμφανίζεται όταν προσπαθείτε να εισαγάγετε μια λειτουργική μονάδα που δεν μπορεί να βρεθεί.
Για παράδειγμα, ο παρακάτω κώδικας με τις προσπάθειες εισαγωγής των panda της βιβλιοθήκης ανάλυσης δεδομένων παρουσιάζει ένα τέτοιο σφάλμα επειδή η μονάδα δεν έχει εγκατασταθεί ακόμη.
Το μήνυμα ImportError που δημιουργήθηκε φαίνεται παρακάτω:
File "/home/madici/Desktop/helloworld.py", line 1, in <module> import pandas ModuleNotFoundError: No module named 'pandas'
Για να επιλύσετε ένα τέτοιο σφάλμα, βεβαιωθείτε ότι οι μονάδες που προσπαθείτε να εισαγάγετε έχουν εγκατασταθεί. Σε περίπτωση που αυτό δεν λύσει το σφάλμα, ελέγξτε εάν χρησιμοποιείτε τη σωστή ορθογραφία για τη λειτουργική μονάδα και τη σωστή διαδρομή αρχείου για πρόσβαση στη λειτουργική μονάδα.
ValueError
Αυτή είναι μια εξαίρεση που συμβαίνει όταν μια συνάρτηση στην Python λαμβάνει μια τιμή του σωστού τύπου δεδομένων αλλά η τιμή είναι μια ακατάλληλη τιμή. Για παράδειγμα, η συνάρτηση Math.sqrt() που χρησιμοποιείται για την εύρεση της τετραγωνικής ρίζας των αριθμητικών τιμών θα επιστρέψει ένα ValueError εάν περάσετε έναν αρνητικό αριθμό.
Όσο και αν η τιμή θα είναι του σωστού τύπου, δηλαδή μια αριθμητική τιμή, το να είναι αρνητικό την καθιστά ακατάλληλη τιμή για το
Η συνάρτηση int() που μετατρέπει έναν αριθμό ή μια συμβολοσειρά θα επιστρέψει ένα ValueError εάν περάσετε μια συμβολοσειρά που δεν είναι τιμή αριθμητικής συμβολοσειράς. Η μετάδοση του “123” ή του “45” στη συνάρτηση δεν επιστρέφει σφάλμα, καθώς οι συμβολοσειρές μπορούν να μετατραπούν στην κατάλληλη ακέραια τιμή.
Ωστόσο, εάν μεταβιβάσετε μια συμβολοσειρά που δεν είναι αριθμητική τιμή συμβολοσειράς, όπως “Hello”, επιστρέφει ένα ValueError. Αυτό συμβαίνει επειδή το “Hello” αν και είναι συμβολοσειρά, είναι ακατάλληλο καθώς δεν έχει ακέραιο ισοδύναμο.
Ένα παράδειγμα κώδικα που δημιουργεί ένα ValueError φαίνεται παρακάτω:
# Value error resulting from inappropriate int value in sqrt() import math num = -64 root = math.sqrt(num) print(root) # Value error resulting from passing a string with no integer # equivalent into int() function numString = "Hello" num = int(numString) print(num)
Τα σφάλματα από τον παραπάνω κώδικα φαίνονται παρακάτω:
Το μήνυμα σφάλματος που δημιουργείται είναι το εξής:
File "/home/madici/Desktop/helloworld.py", line 4, in <module> root = math.sqrt(num) ^^^^^^^^^^^^^^ ValueError: math domain error
Για να διορθώσετε το σφάλμα, χρησιμοποιήστε τις κατάλληλες τιμές στις συναρτήσεις όπως φαίνεται παρακάτω:
import math num = 64 root = math.sqrt(num) print(root) numString = "5231" num = int(numString) print(num)
Σφάλμα IO
Το IOError(Input/Output Error) είναι μια εξαίρεση που προκύπτει όταν μια λειτουργία εισόδου ή εξόδου αποτυγχάνει. Αυτό μπορεί να προκληθεί από την προσπάθεια πρόσβασης σε ένα αρχείο που δεν υπάρχει, την ανεπαρκή αποθήκευση δίσκου στη συσκευή σας, την προσπάθεια πρόσβασης σε ένα αρχείο στο οποίο δεν έχετε επαρκή δικαιώματα πρόσβασης ή όταν προσπαθείτε να αποκτήσετε πρόσβαση σε ένα αρχείο που χρησιμοποιείται αυτήν τη στιγμή από άλλες λειτουργίες.
Μέθοδοι όπως open(), read(), write() και close() που χρησιμοποιούνται συνήθως κατά την εργασία με αρχεία είναι αυτές που είναι πιθανό να προκαλέσουν ένα τέτοιο σφάλμα.
Εξετάστε τον παρακάτω κώδικα που προσπαθεί να ανοίξει ένα αρχείο που ονομάζεται “notes.txt” το οποίο δεν υπάρχει. Ο κώδικας καταλήγει σε ένα IOError που προκαλεί το FileNotFoundError:
Με το ακόλουθο μήνυμα λάθους:
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'
Για να αποφύγετε το παραπάνω σφάλμα, το μόνο που χρειάζεται να κάνετε είναι να βεβαιωθείτε ότι το αρχείο “notes.txt” υπάρχει στον κατάλογο στον οποίο εκτελείτε το τερματικό. Ένας άλλος τρόπος για να χειριστείτε τα IOErrors είναι να χρησιμοποιήσετε το μπλοκ try εκτός, όπως φαίνεται παρακάτω:
ΌνομαΣφάλμα
Το NameError είναι μια εξαίρεση που θα συναντήσετε όταν προσπαθείτε να χρησιμοποιήσετε μια μεταβλητή, μια συνάρτηση ή μια λειτουργική μονάδα που δεν υπάρχει, δεν έχει οριστεί στο τρέχον εύρος ή δεν της έχει εκχωρηθεί μια τιμή.
Ένα τέτοιο σφάλμα παρουσιάζεται συνήθως όταν γράφετε λάθος ονόματα μεταβλητών ή συναρτήσεων ή τα χρησιμοποιείτε πριν οριστούν. Η χρήση μιας λειτουργικής μονάδας χωρίς την εισαγωγή της θα έχει επίσης ως αποτέλεσμα ένα σφάλμα ονόματος.
Ο ακόλουθος κώδικας θα οδηγήσει σε εξαίρεση NameError:
# name error arises because the math module has not been imported num = 64 root = math.sqrt(64) print(root) # NameError arises because x is used before it is defined y = 23 print(x) #NameEror because function name is not defined def greet(): print("Good morning") great() #ameError: name 'great' is not defined
Τα ακόλουθα μηνύματα σφάλματος προκύπτουν από τον παραπάνω κώδικα:
Ένα δείγμα μηνύματος NameError εμφανίζεται παρακάτω:
File "/home/madici/Desktop/helloworld.py", line 3, in <module> root = math.sqrt(64) ^^^^ NameError: name 'math' is not defined
Για να επιλύσετε ένα τέτοιο σφάλμα ονόματος, βεβαιωθείτε ότι δεν χρησιμοποιείτε λειτουργικές μονάδες πριν τις εισαγάγετε, δεν χρησιμοποιείτε μεταβλητές ή συναρτήσεις πριν τις ορίσετε και ότι δεν γράφετε σωστά ονόματα συναρτήσεων ή μεταβλητών:
import math num = 64 root = math.sqrt(64) print(root) y = 23 print(y) def greet(): print("Good morning") greet()
IndexError
Το IndexError είναι μια εξαίρεση που προκύπτει όταν προσπαθείτε να αποκτήσετε πρόσβαση σε ένα ευρετήριο σε μια λίστα ή πλειάδα που βρίσκεται εκτός εύρους. Σκεφτείτε την παρακάτω λίστα:
list1 = [1, 2, 3, 4, 5]
Η λίστα έχει πέντε στοιχεία. Η Python μετράει ευρετήρια από 0 (μηδέν). Επομένως, η παραπάνω λίστα έχει δείκτες που κυμαίνονται από 0 έως n-1, με το n να είναι ο αριθμός ή τα στοιχεία στη λίστα. Σε αυτήν την περίπτωση, το ευρετήριο ή η λίστα θα κυμαίνεται από 0 έως 4.
Εάν προσπαθήσετε να αποκτήσετε πρόσβαση σε ένα στοιχείο με ευρετήριο μεγαλύτερο από 4, θα εμφανιστεί ένα IndexError επειδή το ευρετήριο βρίσκεται εκτός εύρους στη λίστα από την οποία προσπαθείτε να αποκτήσετε πρόσβαση σε ένα στοιχείο. Ο παρακάτω κώδικας δημιουργεί ένα IndexError:
list1 = [1, 2, 3, 4, 5] item = list1[6] #IndexError because the list index is out of range print(item)
Το σφάλμα από τον κώδικα φαίνεται παρακάτω:
Το μήνυμα IndexError που δημιουργήθηκε είναι το εξής:
File "/home/madici/Desktop/helloworld.py", line 2, in <module> item = list1[6] #IndexError because the list index is out of range ~~~~~^^^ IndexError: list index out of range
Ο καλύτερος τρόπος για να αποφύγετε ένα IndexError είναι να χρησιμοποιήσετε τις συναρτήσεις range() και len() για να διασφαλίσετε ότι έχετε πρόσβαση μόνο σε στοιχεία που βρίσκονται εντός εύρους όπως:
list1 = [1, 2, 3, 4, 5] for i in range(len(list1)): print(list1[i])
Σφάλμα κλειδιού
Το KeyError είναι μια εξαίρεση που προκύπτει όταν προσπαθείτε να αποκτήσετε πρόσβαση σε ένα στοιχείο από ένα λεξικό χρησιμοποιώντας ένα κλειδί και το κλειδί δεν βρίσκεται στο λεξικό. Σκεφτείτε το παρακάτω λεξικό:
cities = {"Canada": "Ottawa", "USA": "Washington", "Italy": "Rome"}
Τα κλειδιά στο λεξικό είναι “Καναδάς”, “ΗΠΑ”, “Ιταλία”. Μπορείτε να αποκτήσετε πρόσβαση στα στοιχεία από το λεξικό πόλεων χρησιμοποιώντας τα τρία πλήκτρα. Ωστόσο, εάν προσπαθήσετε να αποκτήσετε πρόσβαση σε ένα στοιχείο χρησιμοποιώντας ένα κλειδί που δεν υπάρχει, όπως το “Brazil”, θα αντιμετωπίσετε ένα KeyError, όπως φαίνεται παρακάτω:
Το μήνυμα KeyError που δημιουργήθηκε φαίνεται παρακάτω:
File "/home/madici/Desktop/helloworld.py", line 6, in <module> print(cities["Brazil"]) ~~~~~~^^^^^^^^^^ KeyError: 'Brazil'
Για να επιλύσετε ένα Σφάλμα κλειδιού, βεβαιωθείτε ότι τα κλειδιά που χρησιμοποιείτε για πρόσβαση σε στοιχεία σε ένα λεξικό υπάρχουν στην πραγματικότητα στο λεξικό. Για να το κάνετε αυτό, μπορείτε να κάνετε μια δήλωση if…else όπως αυτή:
cities = {"Canada": "Ottawa", "USA": "Washington", "Italy": "Rome"} country = "Canada" if country in cities: print("The capital city of " + country + " is " + cities[country]) else: print("The key " + country + " is not present in the cities dictionary")
Με αυτόν τον τρόπο, θα αποφύγετε την εμφάνιση σφαλμάτων κλειδιού κατά την πρόσβαση σε στοιχεία από ένα λεξικό
συμπέρασμα
Κατά την κωδικοποίηση σε Python, ανεξάρτητα από το επίπεδο εξειδίκευσής σας, είναι βέβαιο ότι θα αντιμετωπίσετε σφάλματα. Επομένως, φροντίστε να εξοικειωθείτε με τους διαφορετικούς τύπους σφαλμάτων που επισημαίνονται στο άρθρο για να βεβαιωθείτε ότι είστε σε θέση να τα χειριστείτε όταν προκύψουν.
Μπορείτε επίσης να εξερευνήσετε μερικά χρήσιμα Python one-liners για να απλοποιήσετε κοινές εργασίες.