Inheritance in Python
You’re almost always using some form of inheritance within Python, even if you don’t explicitly declare it. To demonstrate that, I’m going to use the Python interactive shell. I’m going to start by creating a new class called
MyClass—a very creative name.
I want to leave this class blank, and so I’ll just write
pass is a special keyword that will allow you to create a function, class, or loop that is effectively empty.
Now, I will instantiate this class into a new object called
c. Python has a built-in function called
dir(), which returns a list of all the members of the class you pass in. A class’s members are just the attributes and methods that make up the class, including the special
.__init__() method that’s used for object instantiation.
00:59 But we didn’t declare any attributes or methods, so this class has no members, right? Let’s find out.
That’s probably not what you were expecting. What are all of these members with double underscores (
__), and where are they coming from? These members are actually all methods called magic methods, or dunder methods,
named after their double underscores. Some of these may look familiar to you, such as
__init__, which we use as the constructor for constructing new classes.
We also used
__init__ to declare instance attributes. To explain where these are coming from, let me create one more object and list its members.
And would you look at that? It looks like the
o object and the
c object have very similar members, except the
c object—which came from our custom class—has some extra members, like
You might be able to guess what’s going on here, but let me explain. This
o object was instantiated from the
object class, which is super confusing considering we’ve been calling every instance of any class an object. Well, this
object class is not a class that we define ourselves.
It’s built into Python and it’s this
object class that defines these strange members that we’re seeing. And, as it turns out, every custom class that we create automatically inherits from this
object class behind the scenes, even if we don’t explicitly make it.
That explains why the
c object has all of these members too—it inherited it from the
object class. The extra members present in our custom class came from elsewhere, but that’s beyond the scope of this course.
The point is every class in Python implicitly inherits from this
object superclass, which defines all these magic methods that Python uses to manage our objects.
03:14 Another place where inheritance is used is with exceptions. Exception objects are special in that they can be thrown up a call stack and caught anywhere along that stack.
03:27 If no code catches that exception object before it reaches the top, the program crashes and you’re left with a stack trace. If you’re interested in learning more about exceptions, we have a course for that, which I will link down in the video notes below.
03:45 Let’s see how they work with inheritance. Someone new to exceptions might try to create their own exception class as if it were a normal class, just like this.
Exceptions can be raised with the
raise keyword. This is similar to throw in other languages. All right, we got a stack trace—but it’s not from our exception.
MyError. Python has identified that we’re trying to create a custom exception class, but we didn’t do it right.
It’s saying that our class must inherit from
BaseException is a built-in class provided for all error types. There are lots of classes that derive from
BaseException, such as
ArithmeticError, which means that we can use them in place of
SyntaxError inherits from
BaseException, it means
SyntaxError is a
BaseException because it inherits all of the members of
BaseException. What specific exception type you inherit from depends on the situation at hand.
BaseException is not supposed to be inherited from directly, so we’ll choose its next child, a class called
This is the class that the official documentation recommends inheriting from. I’ll redefine the
MyError class, but this time I’ll put the name of the class I want to inherit from in parentheses, after the class name.
MyError is now an
Exception, literally. I could write
pass in here and leave the custom exception type blank,
but I want to do one more thing. Exceptions usually have some sort of message that’s intended to tell the user or developer what went wrong. The
Exception class contains an attribute for the message,
and as such, it’s been passed down to our
MyError class. To use it, we first must add an
.__init__() method to this class. This exception will need to be passed a
message when it is raised.
Now, we can use the
super() function to call the
.__init__() method of
passing in the
message. In essence, when we create a
MyError object, we’re asking for a
message and then passing it to the parent.
Finally, now that we’re done writing our class, we can raise
MyError, passing in whatever
message we want. I’ll choose a particularly unhelpful one that you might’ve seen before.
There’s our custom exception with the message. This was possible due to inheritance. We created a custom class that inherited from
Exception, so Python recognized our class as an exception.
We even utilized the inherited
.message attribute to allow our custom exception class to be utilized with a custom message.
He could have been referring to this: realpython.com/courses/introduction-python-exceptions/
where can I find all your courses?? pls provide link..
You can click on an instructor’s name to see all of their courses. For example, all of Austin’s courses are listed here on his team profile: realpython.com/team/acepalia/
I found this section on inheritance a bit hard to follow. Why did you not have to create an instance of MyError?
@muondude He did create an instance of
MyError by calling it with a pair of parentheses. Note that in Python, you can raise either an exception class or its instance:
>>> class MyError(Exception): ... pass ... >>> # Class: >>> raise MyError Traceback (most recent call last): File "<input>", line 1, in <module> raise MyError MyError >>> # Class instance: >>> raise MyError("Details about the error...") Traceback (most recent call last): File "<input>", line 1, in <module> raise MyError("Details about the error...") MyError: Details about the error...
It makes sense to raise an instance of an exception class when you need to provide some context around the error that occurred.
Become a Member to join the conversation.
leilanobatova on June 26, 2020
Austin said in video that link to the course about Exceptions will be under the video, I couldn’t find one. It would be super helpful to have one here. Thanks!