|
| https://realpython.com/ |
| Start Here | https://realpython.com/start-here/ |
|
Learn Python
| https://realpython.com/lessons/using-abstract-base-classes-code/ |
| Your Learning Plan →Your personalized Python learning plan | https://realpython.com/account/learning-plan/ |
| Python Tutorials →In-depth articles and video courses | https://realpython.com/search?kind=article&kind=course&order=newest&_from=nav_library |
| Learning Paths →Guided study plans for accelerated learning | https://realpython.com/learning-paths/ |
| Quizzes & Exercises →Check your learning progress | https://realpython.com/search?kind=exercise&kind=quiz&_from=nav_library |
| Browse Topics →Focus on a specific area or skill level | https://realpython.com/tutorials/all/ |
| Reference →Concise definitions for common Python terms | https://realpython.com/ref/ |
| Mentor AI →NewYour personal Python mentor | https://realpython.com/mentor/ |
| Office Hours →Live Q&A calls with Python experts | https://realpython.com/office-hours/ |
| Community Chat →Learn with other Pythonistas | https://realpython.com/community/ |
| Live Courses →Live, instructor-led Python courses | https://realpython.com/live/ |
| Books →Round out your knowledge and learn offline | https://realpython.com/products/books/ |
| Podcast →Hear what’s new in the world of Python | https://realpython.com/podcasts/rpp/ |
| Unlock All Content and Become a Python Expert →Get unlimited access to all Real Python has to offer | https://realpython.com/account/join/?from=navbar_learn |
| Unlock All Content →Become a Python Expert | https://realpython.com/account/join/?from=navbar_learn |
|
More
| https://realpython.com/lessons/using-abstract-base-classes-code/ |
| Learner Stories | https://realpython.com/learner-stories/ |
| Python Newsletter | https://realpython.com/newsletter/ |
| Python Job Board | https://www.pythonjobshq.com |
| Meet the Team | https://realpython.com/team/ |
| Become a Contributor | https://realpython.com/jobs/ |
| Search | https://realpython.com/search |
| https://realpython.com/search |
| Join | https://realpython.com/account/join/ |
| Sign‑In | https://realpython.com/account/login/?intent=navbar&next=%2Flessons%2Fusing-abstract-base-classes-code%2F |
| Unlock This Lesson | https://realpython.com/account/join/?utm_source=rp_lesson&utm_content=duck-typing-python |
| Unlock This Lesson | https://realpython.com/account/join/?utm_source=rp_lesson&utm_content=duck-typing-python |
|
| https://realpython.com/courses/duck-typing-python/#team |
| Getting to Know Duck Typing in Python | https://realpython.com/courses/duck-typing-python/ |
| Negar Vahid | https://realpython.com/courses/duck-typing-python/#team |
| Recommended Tutorial | https://realpython.com/duck-typing-python/ |
| Course Slides (.pdf) | https://realpython.com/courses/duck-typing-python/downloads/duck-typing-slides/ |
| Sample Code (.zip) | https://realpython.com/courses/duck-typing-python/downloads/duck-typing-code/ |
| Ask a Question | https://realpython.com/lessons/using-abstract-base-classes-code/#discussion |
| https://realpython.com/feedback/survey/course/duck-typing-python/liked/?from=lesson-title |
| https://realpython.com/feedback/survey/course/duck-typing-python/disliked/?from=lesson-title |
| Contents | https://realpython.com/lessons/using-abstract-base-classes-code/#description |
| Transcript | https://realpython.com/lessons/using-abstract-base-classes-code/#transcript |
| Discussion | https://realpython.com/lessons/using-abstract-base-classes-code/#discussion |
| 00:00 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=0.565 |
| So the goal here is to create an ABC called Vehicle | https://realpython.com/lessons/using-abstract-base-classes-code/#t=0.565 |
| that defines the required interface that you need | https://realpython.com/lessons/using-abstract-base-classes-code/#t=3.975 |
| and makes all your vehicle classes inherit from it. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=6.805 |
| 00:09 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=9.955 |
| First, you need to import ABC, | https://realpython.com/lessons/using-abstract-base-classes-code/#t=9.955 |
| and abstractmethod from the abc module. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=11.885 |
| from abc import ABC, all letters | https://realpython.com/lessons/using-abstract-base-classes-code/#t=14.895 |
| capitalized, and abstractmethod. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=19.795 |
| 00:24 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=24.775 |
| Then you need to define your base class: class | https://realpython.com/lessons/using-abstract-base-classes-code/#t=24.775 |
| Vehicle(ABC). | https://realpython.com/lessons/using-abstract-base-classes-code/#t=28.175 |
| Then you can initialize the required attributes using | https://realpython.com/lessons/using-abstract-base-classes-code/#t=31.775 |
| the __init__ magic method. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=34.405 |
| 00:36 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=36.125 |
| Moving this method to the base class saves you from | https://realpython.com/lessons/using-abstract-base-classes-code/#t=36.125 |
| repetitive code in your subclasses. def | https://realpython.com/lessons/using-abstract-base-classes-code/#t=39.385 |
| __init__(self, | https://realpython.com/lessons/using-abstract-base-classes-code/#t=43.645 |
| make, model, color): | https://realpython.com/lessons/using-abstract-base-classes-code/#t=46.285 |
| self.make = make | https://realpython.com/lessons/using-abstract-base-classes-code/#t=49.325 |
| self.model = model and | https://realpython.com/lessons/using-abstract-base-classes-code/#t=54.005 |
| self.color = color. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=59.765 |
| 01:04 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=64.605 |
| Now for the .start, .stop, and .drive methods, | https://realpython.com/lessons/using-abstract-base-classes-code/#t=64.605 |
| you need to define the required methods as abstract methods. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=68.325 |
| You can use the abstractmethod decorator | https://realpython.com/lessons/using-abstract-base-classes-code/#t=72.165 |
| that you imported earlier. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=74.825 |
| 01:16 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=76.975 |
| Note that the abstract methods don’t provide a | https://realpython.com/lessons/using-abstract-base-classes-code/#t=76.975 |
| specific implementation. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=79.905 |
| They just raise NotImplementedError exceptions. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=81.175 |
| So @abstractmethod def | https://realpython.com/lessons/using-abstract-base-classes-code/#t=86.045 |
| let’s start with start(self): | https://realpython.com/lessons/using-abstract-base-classes-code/#t=90.875 |
| 01:36 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=96.365 |
| and you will | https://realpython.com/lessons/using-abstract-base-classes-code/#t=96.365 |
| raise NotImplementedError you can say ("Start | https://realpython.com/lessons/using-abstract-base-classes-code/#t=100.935 |
| must be implemented.") | https://realpython.com/lessons/using-abstract-base-classes-code/#t=103.685 |
| 01:51 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=111.205 |
| So when you’re creating a class without the needed methods, | https://realpython.com/lessons/using-abstract-base-classes-code/#t=111.205 |
| right away you’ll get an error. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=114.755 |
| Okay, let’s do the same thing for stop | https://realpython.com/lessons/using-abstract-base-classes-code/#t=117.375 |
| and drive. @abstract method | https://realpython.com/lessons/using-abstract-base-classes-code/#t=119.485 |
| def stop(self): raise | https://realpython.com/lessons/using-abstract-base-classes-code/#t=125.215 |
| NotImplementedError, | https://realpython.com/lessons/using-abstract-base-classes-code/#t=130.245 |
| I can say stop() | https://realpython.com/lessons/using-abstract-base-classes-code/#t=132.965 |
| must be implemented. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=137.055 |
| 02:21 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=141.245 |
| And exactly the same thing for drive: @abstract method | https://realpython.com/lessons/using-abstract-base-classes-code/#t=141.245 |
| 02:27 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=147.775 |
| def drive(self): | https://realpython.com/lessons/using-abstract-base-classes-code/#t=147.775 |
| 02:32 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=152.475 |
| raise, NotImplemented` | https://realpython.com/lessons/using-abstract-base-classes-code/#t=152.475 |
| Error drive() | https://realpython.com/lessons/using-abstract-base-classes-code/#t=155.105 |
| must be implemented. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=160.015 |
| 02:44 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=164.735 |
| Okay, this is your base class. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=164.735 |
| You can save it. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=166.937 |
| And also one thing to look out for is | https://realpython.com/lessons/using-abstract-base-classes-code/#t=169.125 |
| that you can instantiate an ABC directly. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=171.345 |
| They work as an API template for other classes to adhere to. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=175.495 |
| 03:00 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=180.215 |
| Let’s actually try this out in the terminal. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=180.215 |
| Let’s say from vehicle_abc import Vehicle. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=184.245 |
| Okay? | https://realpython.com/lessons/using-abstract-base-classes-code/#t=188.355 |
| And then let’s try to just instantiate from Vehicle. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=189.455 |
| 03:12 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=192.575 |
| So Vehicle("Ford", "Mustang", "Red"). | https://realpython.com/lessons/using-abstract-base-classes-code/#t=192.575 |
| Okay? | https://realpython.com/lessons/using-abstract-base-classes-code/#t=195.492 |
| When you run this code, you get a type error. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=196.505 |
| You can’t instantiate abstract class Vehicle | https://realpython.com/lessons/using-abstract-base-classes-code/#t=199.655 |
| with abstract methods | https://realpython.com/lessons/using-abstract-base-classes-code/#t=202.785 |
| drive, start, and stop. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=204.285 |
| 03:26 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=206.285 |
| Okay? | https://realpython.com/lessons/using-abstract-base-classes-code/#t=206.285 |
| So you need to create | https://realpython.com/lessons/using-abstract-base-classes-code/#t=206.495 |
| subclasses. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=207.885 |
| Okay, | https://realpython.com/lessons/using-abstract-base-classes-code/#t=210.492 |
| back to the code. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=211.795 |
| Now you’re creating specific vehicles | https://realpython.com/lessons/using-abstract-base-classes-code/#t=212.811 |
| by inheriting from the Vehicle class | https://realpython.com/lessons/using-abstract-base-classes-code/#t=214.975 |
| and implementing all the required methods. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=217.895 |
| 03:40 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=220.785 |
| It’s actually almost the same code as duck typing, | https://realpython.com/lessons/using-abstract-base-classes-code/#t=220.785 |
| but now you’re inheriting from your Vehicle ABC. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=224.135 |
| So class Car(Vehicle): | https://realpython.com/lessons/using-abstract-base-classes-code/#t=227.735 |
| 03:53 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=233.295 |
| def start(self): | https://realpython.com/lessons/using-abstract-base-classes-code/#t=233.295 |
| 03:57 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=237.335 |
| and then you’re printing, “The car is starting.” | https://realpython.com/lessons/using-abstract-base-classes-code/#t=237.335 |
| And you’re going to do the same thing for stop and drive, | https://realpython.com/lessons/using-abstract-base-classes-code/#t=242.775 |
| and you’re going to do Truck and add start, stop, and drive. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=246.095 |
| 04:10 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=250.225 |
| Okay? | https://realpython.com/lessons/using-abstract-base-classes-code/#t=250.225 |
| So it’ll look like | https://realpython.com/lessons/using-abstract-base-classes-code/#t=251.111 |
| this and you’re done. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=253.915 |
| You’ve replaced duck typing with ABCs. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=256.695 |
| And please note that in this case, your classes are | https://realpython.com/lessons/using-abstract-base-classes-code/#t=259.615 |
| coupled with the base class. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=262.505 |
| 04:24 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=264.425 |
| This can be a limitation | https://realpython.com/lessons/using-abstract-base-classes-code/#t=264.425 |
| because you won’t be able to reuse one | https://realpython.com/lessons/using-abstract-base-classes-code/#t=265.955 |
| of your classes in a different project | https://realpython.com/lessons/using-abstract-base-classes-code/#t=267.755 |
| unless you also take the Vehicle class with you. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=269.295 |
| 04:33 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=273.425 |
| Okay? | https://realpython.com/lessons/using-abstract-base-classes-code/#t=273.425 |
| Now, let’s create a Jeep class | https://realpython.com/lessons/using-abstract-base-classes-code/#t=273.753 |
| that inherits from Vehicle | https://realpython.com/lessons/using-abstract-base-classes-code/#t=276.265 |
| without providing the required interface. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=278.305 |
| Let’s see what happens. class | https://realpython.com/lessons/using-abstract-base-classes-code/#t=280.445 |
| Jeep(Vehicle): | https://realpython.com/lessons/using-abstract-base-classes-code/#t=285.445 |
| 04:49 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=289.485 |
| Okay, let’s just say def | https://realpython.com/lessons/using-abstract-base-classes-code/#t=289.485 |
| start(self): and say print("The Jeep is starting.") | https://realpython.com/lessons/using-abstract-base-classes-code/#t=292.385 |
| and let’s just keep it like this. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=297.795 |
| Let’s not implement drive and stop. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=299.545 |
| 05:01 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=301.685 |
| Okay? | https://realpython.com/lessons/using-abstract-base-classes-code/#t=301.685 |
| Let’s see what happens. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=301.895 |
| And then let’s say jeep = Jeep( | https://realpython.com/lessons/using-abstract-base-classes-code/#t=303.875 |
| "Land Rover", "Defender", and | https://realpython.com/lessons/using-abstract-base-classes-code/#t=307.515 |
| 05:13 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=313.475 |
| "Black"). | https://realpython.com/lessons/using-abstract-base-classes-code/#t=313.475 |
| As you probably remember, these are the make model | https://realpython.com/lessons/using-abstract-base-classes-code/#t=315.755 |
| and color of the car. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=318.355 |
| And let’s try and see what happens. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=320.195 |
| You get a type error, `Can’t instantiate abstract class Jeep with | https://realpython.com/lessons/using-abstract-base-classes-code/#t=322.915 |
| abstract methods drive, stop. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=328.015 |
| 05:31 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=331.285 |
| Basically, you just need to implement drive and stop, | https://realpython.com/lessons/using-abstract-base-classes-code/#t=331.285 |
| and this is exactly the type of error we were looking for. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=333.995 |
| What happened here was | https://realpython.com/lessons/using-abstract-base-classes-code/#t=337.645 |
| that you only implemented the start method, | https://realpython.com/lessons/using-abstract-base-classes-code/#t=338.695 |
| which doesn’t fulfill the complete interface. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=341.385 |
| 05:43 | https://realpython.com/lessons/using-abstract-base-classes-code/#t=343.605 |
| When you try to instantiate this class, you get a type error | https://realpython.com/lessons/using-abstract-base-classes-code/#t=343.605 |
| because the required interface is incomplete. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=346.605 |
| This behavior is exactly why ABCs are important | https://realpython.com/lessons/using-abstract-base-classes-code/#t=349.885 |
| because they enforce specific interfaces. | https://realpython.com/lessons/using-abstract-base-classes-code/#t=353.775 |
| Become a Member | https://realpython.com/account/join/ |
| https://realpython.com/lessons/using-abstract-base-classes/ |
| Overview | https://realpython.com/courses/duck-typing-python/ |
| https://realpython.com/lessons/checking-types-explicitly/ |
|
Getting Started With Duck Typing (Overview) 04:22
| https://realpython.com/videos/duck-typing-python-overview/ |
|
Exploring Duck Typing 03:11
| https://realpython.com/videos/exploring-duck-typing/ |
|
Examining Duck Typing and Polymorphism 03:48
| https://realpython.com/videos/examining-duck-typing-polymorphism/ |
|
Comparing Duck Typing in Python's Built-in Types 02:23
| https://realpython.com/videos/comparing-duck-typing-builtin-types/ |
|
Exercise: Toast Anything with Duck Typing 08:00
| https://realpython.com/lessons/exercise-toast-anything-duck-typing/ |
|
Exploring Alternatives to Duck Typing 01:27
| https://realpython.com/lessons/alternatives-duck-typing/ |
|
Using Abstract Base Classes 03:36
| https://realpython.com/lessons/using-abstract-base-classes/ |
|
Using Abstract Base Classes: Code 05:57
| https://realpython.com/lessons/using-abstract-base-classes-code/ |
|
Checking Types Explicitly 02:38
| https://realpython.com/lessons/checking-types-explicitly/ |
|
Checking Types Explicitly: Code 01:38
| https://realpython.com/lessons/checking-types-explicitly-code/ |
|
Tackling Type Hints 02:58
| https://realpython.com/lessons/tackling-type-hints/ |
|
Combining ABCs And Duck Typing 02:33
| https://realpython.com/lessons/abcs-duck-typing/ |
|
Combining ABCs And Duck Typing: Code 02:21
| https://realpython.com/lessons/abcs-duck-typing-code/ |
|
Exercise: Enforce an Appliance Interface with an ABC 09:00
| https://realpython.com/lessons/exercise-appliance-interface-abc/ |
|
Getting to Know Duck Typing in Python (Summary) 01:21
| https://realpython.com/lessons/duck-typing-python-summary/ |
| Privacy Policy | https://realpython.com/privacy-policy/ |
Viewport: width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover