Covering Built-In Exceptions

00:00 In the previous lesson, I showed you how to raise and handle an exception. In this lesson, I’ll be talking about some of the exceptions that come with Python.

00:10 Python is exceptional. I told you I’d keep it up. In fact, it’s so exceptional, it has over sixty built-in exceptions. This link shows the documentation where you’ll find them all listed.

00:23 In the previous lesson, I mentioned that exceptions inherit from an object hierarchy. The root of that hierarchy is the BaseException class, and the topmost one you should use is the Exception class itself.

00:37 This is the one I showed you in the previous lesson. That being said, you probably shouldn’t use this one either. It’s a little too generic. Let’s talk about the eight most common exceptions you’re likely to run into in Python code.

00:52 ImportError gets raised if the import statement can’t load a module. If you’ve coded at all, you’ve likely seen the NameError. This one gets raised if you reference something that isn’t in the local or global scope.

01:06 This one could also be called spelling error as misspelling a variable is the most common cause, at least for me that is. AttributeError gets raised if you reference an attribute that doesn’t exist on an object.

01:19 It can be a bit more technical than that as Python has several things you can do to override attribute behavior, but the typical case is trying to use an attribute that isn’t there.

01:29 IndexError gets raised when you attempt to use an index in a sequence that’s out of range of that sequence. Backup covered in the previous lesson as well.

01:39 KeyError is kind of like the IndexError, but for dictionaries. This gets raised if you try to reference a non-existing key. ZeroDivisionError gets raised if you attempt to divide a number by zero or try to do modulo zero.

01:55 Mathematicians get pretty cranky when you try to do this. Python just raises an exception. TypeError gets raised when you try to do something that isn’t compatible with an object’s type.

02:06 For example, if you attempt to divide a string by an integer, you get a TypeError as strings don’t support division.

02:14 ValueError is probably one of the ones I see and use the most. This is a bit of a catch-all for things where the type of the argument is correct, but the value is unsupported.

02:24 Say you had a function that was supposed to take strings with only vowels in them. You might raise a ValueError if the string passed in contained consonants.

02:33 It’s still a string in both cases, so it isn’t a TypeError, but if the function’s expecting only vowels and finds something else, a ValueError is the appropriate thing to raise.

02:45 Although these exceptions all come with Python, Python’s not the only thing that should raise them, you can as well. In fact, using existing exceptions is encouraged as they fit a pattern that other programmers expect.

02:57 Let me show you an example.

03:00 I’m going to write a function that takes a list or a tuple of numbers and returns a list with the squares of each value of the inputs.

03:14 Here I’m checking if the numbers argument is a list or a tuple,

03:25 and if the function doesn’t get a list or a tuple, it raises a TypeError. This is actually a perfect example of what TypeErrors are for.

03:34 I’ve included a hint in the message body as well, so a programmer seeing it will know why I’ve raised the exception. If this were a program rather than me just futsing about in the REPL, I’d have a docstring for the function, and in that docstring, I’d indicate that this function raises a TypeError and why. You should always document your code.

03:55 With the type checking out of the way,

04:01 this line does the actual work. It’s a list comprehension that creates a list of squared values based on the iterable input. Let me run it, and there you go.

04:15 Some squares. Instead of passing in a list, let me pass in a set.

04:23 And as expected, it raises a TypeError. A couple of things to notice about this exception. First, because it happened inside of a function, there are two lines in the traceback.

04:34 The stack shows line three and line one. Line three is relative to the function declaration, and it’s on the third line of that function where the exception gets raised.

04:45 Line one is relative to the REPL and hence the angle brackets module notation like you saw in the previous lesson where I raised exceptions from the REPL line itself.

04:56 The second thing to note is that this is a bit of a contrived example. Don’t get me wrong, you should raise a TypeError if an iterable without numbers gets passed in, but sets are actually iterable.

05:09 If my code were a little better, I would do type checking to include sets and allow them, but that wouldn’t give me as good an example.

05:19 Now that you’ve seen some of the exceptions that come with Python, it’s time to see how you can write your own. That’s up next.

Become a Member to join the conversation.