Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Mastering Object-Related Exceptions

00:00 As an object-oriented language, Python is powerful and versatile, but with great power comes great… What was it? Responsibility, or in this case, things that can go wrong.

00:12 The main exceptions you need to know about when dealing with Python classes, objects and types are the TypeError, the ValueError, and the AttributeError.

00:22 Example time. Once again, open up the REPL. First, the TypeError. This exception is raised when you apply some function or operation to an object that doesn’t support it.

00:34 Its type is incompatible with that operation. For example, passing an integer to the built-in len() function. len(42) TypeError: object of type 'int' has no len().

00:46 This message highlights that the incompatibility is based on type. These error messages are pretty useful, aren’t they? Something you can do in your own functions is raise an error yourself and provide a more specific error message to the user.

01:00 Here’s an example of how you might do this with a function intended to square an iterable collection of numbers: def squared(numbers):

01:10 try passing numbers to the iter() function,

01:15 except TypeError: raise TypeError(

01:21 passing in the f-string `Expected an iterable, got ‘` the interpolated value of passing numbers to the built-in type() function and accessing its .__name__ attribute from None).

01:39 Return the list comprehension number ** 2 for number in numbers.

01:46 First you try to pass numbers to the iter() function. If numbers isn’t an iterable, iter() will raise a TypeError.

01:53 In that case, you catch the TypeError and raise your own TypeError with a custom message. And if you’re wondering, from None at the end there is used to suppress displaying the originally caught error to keep things cleaner.

02:07 And of course, if no error occurs, the function should return a list of the elements of the original iterable squared. So try it out, pass the list of the integers, [1, 2, 3, 4, 5] to the squared() function and the result are those numbers squared: [1, 4, 9, 16, 25].

02:27 Now with something not iterable like the integer 42,

02:31 beautiful. TypeError: expected an iterable, got 'int' just as you defined in the function. And maybe now you’re wondering what if it’s not the type of the object that’s incompatible, but the value instead.

02:45 Yep. That’s the situation where a ValueError occurs. For an example, look at the built-in float() function. It can take a string and convert it to a float like this: call float() and pass it the number '1' as a string, the output is the float 1.0.

03:02 But if you pass the string 'one' instead,

03:06 ValueError: could not convert string to float: 'one'. The type was fine. Strings can be converted to floats as you saw, but only if the string has the correct value.

03:19 Last up is the AttributeError. This exception is raised when you try to access an attribute of an object that doesn’t exist. Start by creating a class called Example with no contents, only the pass statement. Create an instance of the class: example = Example() and try using notation to access some attribute that isn’t there, like the .status attribute, example.status and we get an AttributeError.

03:49 'Example' object has no attribute ‘status’`. In practice, if you’re dealing with an object that may or may not have the attribute you’re trying to access, you can check if the attribute exists by using the hasattr() function.

04:01 It returns True if the object has the attribute, otherwise it returns False. So for safety, you could try something like this: if hasattr(example, 'status'): print(example.status) else: print("There is no status")

04:26 and of course, we see "There is no status."

04:29 And one more thing, AttributeError also applies to the contents of modules. So, to see: import sys and try to access sys.non_existing

04:43 as you probably expected, AttributeError: module 'sys' has no attribute 'non_existing'.

04:50 I hope everything so far has been adding up for you because in the next lesson we’ll be looking at ArithmeticError exceptions.

Become a Member to join the conversation.