Guidance on Object-Oriented Programming in Python
Key Takeaways
This video provides guidance on object-oriented programming in Python, covering SOLID principles and guiding principles for writing better code, with a focus on the Single-Responsibility Principle and alternatives to inheritance such as composition and delegation, all within the context of Python's unique object-oriented approach and tools like Python 3 style class declarations.
Full Transcript
welcome to object-oriented coding in Python design and guidance my name is Christopher and I will be your guide this is the third part of a multi-part course Parts one and two are about the how of object-oriented coding covering the syntax of classes in Python and how to use its attributes and methods as everything in Python is an object that includes intricate details such as how operations like adding and multiplying apply to your objects through Dunder methods this third part of the course is a little different it's a bit more about the why and approach the focus in this part of the course is about how to build better object-oriented software and in some cases why you maybe shouldn't use oo techniques at all this third part of a three-part course teaches you about how the python object-oriented approach compares to other languages when not to use classes in Python alternatives to inheritance and the solid principles the code in this course was written with python 311. object-oriented coding in Python has gone through some changes over the years and so the code presented here won't work in Python 2 without being altered Python's a bit of a weird Beast language-wise its history is firmly in the procedural style scripting world but it has flavors of functional programming and object-oriented coding inside of it this means you can choose how much or how little you use object-oriented techniques when you code it actually is very object oriented underneath but you don't have to use that mental abstraction if you don't want to if you're coming from other languages especially those which are object-oriented first this leap can be a bit of an adjustment if you're an experienced coder in one language your first tendency when writing code in a new language is to use the style you're familiar with even if it isn't a good fit for your new language as a python coder if you come across a lot of object-oriented code where you're wondering why they didn't just use a dictionary there's a good chance the original writer was an ex-java person or something similar once you do decide to write some object-oriented code whether in python or any other language there are some guiding principles that should be followed this course is primarily about those principles you want to write clean code that can be supported by others structure your code for reuse following the dry that's don't repeat yourself principle and you also want to take advantage of duct typing or more formally polymorphism where the interface to the object determines how it is used and it can be passed around to other code which doesn't have to be concerned with its underlying implementation and once you start building classes on top of each other you want to do so in a fashion where you aren't designing yourself into a corner keeping your code flexible for future changes there's an acronym out there that can help you think about these ideas it's named solid the expansion of which is confusing and a paragraph full so I won't call it anything but solid until you get to that part of the course before spending some time on solid let's talk about whether you should Orient your objects at all in the previous lesson I gave an overview of the course in this lesson I'll talk about when and when not to use an object-oriented approach in Python if you come from a language like Java where everything must be a class your first tendency in Python might be very java-like but python enables several different coding Styles procedural which is script light coding functional which uses things like lambdas and mapreduce and what all the parts of this course have been about object-oriented Concepts having this much choice is powerful but you know that Spider-Man line about great responsibility choosing the wrong techniques May over complicate your job as a programmer let's briefly talk about a couple of other popular languages if you're coming from Jabba or quite frankly C plus plus and although I've never used it I suspect c-sharp falls into this bucket as well simple programs don't need classes at all in Python you should write classes when writing a class is a natural extension of the data you're encapsulating if you have some data attributes you need to keep together and some operations that are dedicated to them then you might want a class for shorter programs you can often get away with using a dictionary a tuple or more specifically a named Tuple or now that python has data classes that might also be a good compromise if you're coming from JavaScript welcome to a saner world sorry just couldn't help but get that dig in classes in JavaScript are prototype based there are a couple of other languages that use this approach as well but they're not as common python like most other object-oriented languages uses a structured declarative approach if you're used to es6 style JavaScript using the class keyword you won't notice much difference syntactically but the underlying mechanics of inheritance are different so you might need to be careful as you dig in and since JavaScript was also originally a procedural language with object-oriented semantics layered on top the easy mixing in Python will be familiar to you unlike most other object-oriented languages python does not strictly enforce the concept of private or protected all things are accessible there is a convention that members with a leading underscore are non-public and users of your class shouldn't rely on those kinds of attributes but it is just a convention they can still be used through the interface there's also some weird black magic um okay Gray magic dirty white off-page magic where double underscores cause a member to be name mangled that's a fancy way of saying it is automatically renamed this kind of works like private in that it hides it away but if you know how to produce a mangled name you can still call it you probably shouldn't but the language doesn't prevent you it's sort of a thin ice sign rather than a fence you can ignore it but there might be some consequences python has had object-oriented concepts for a long time but it changed how they work in Python 2.2 in that version oh so long ago the underlying hierarchy was changed so the ultimate ancestor of your class in Python 2 1 and 2-2 are different for backwards compatibility 2-2 allowed you to declare a class using either the old style or the new style to indicate you wanted a new stop class you inherit from the object class to declare a person using the new class it looks like this where person inherits from object of course the new in the phrase new style is rather dated it's from very long ago the compatibility supporting both old and new Styles was available all the way up to 2 7. since the end of life of python 27 was in 2020 that new thing continued to exist for almost two decades by contrast Python 3 only uses the new style of classes the old style from before python 2 2 no longer works that made the whole inherit from object things seem a little verbose so its need was dropped you can still use that syntax if you'd like especially if you're writing code that has to be compatible with python 2 and 3. essentially in Python 3 both of these declarations result in the same thing this of course can cause some confusion if you use the Python 3 style without the object in Python 2 you're not going to get the old new style but the actual very old old style and some rather unexpected class behaviors I get why it's done it definitely looks better without the object but this is a massive foot gun for folks maintaining older code so be careful if you're still straddling the python 2 Python 3 world okay enough history and potential toll removal when should you use a class well it might be easier to outline when not to if you have a small script that doesn't have a lot of data structures or you need really Speedy code if the code base you're maintaining already doesn't for example it's heavily functional or the code is mostly procedural your teammates will like you better if you stay consistent with the code that exists already if you are writing object-oriented code you don't necessarily have to use inheritance to gain the advantage of code reuse inheritance can be described as an is a relationship for example a car is a vehicle so I might have my car class extend my vehicle class one alternative to this structure is a has a relationship this is also known as composition this is the case where the attribute of one object references another you can still do duct typing and polymorphic interfaces using this mechanism and there aren't any surprises when someone changes a base class say adding a method that trickles down to the children with composition that won't affect you unless you want to call it on the related object there are some special kinds of composition that have their own names delegation is composition with execution handoff your object references another object and the owner has methods within which it calls the delegated object it's a kind of wrapper if you took part two of this course the hex color container example was a list delegate exposing its own interface but implementing the underlying storage with a reference to a non-public list this was a kind of Delegation [Music] an even more specific kind of composition is dependency injection it's still a wrapper but this time what you're wrapping is an object that is passed in each call gets proxied to the injected object this means you can change the behavior of the wrapping class by passing in injecting a different object this pattern can be useful when you want to perform similar tasks on related objects for example if you've got a class that abstracts database interactions injecting an object that implements specific database details allows you to code against the generic interface while someone else worries about how it is done a big Advantage here is someone else can write another injectable object that implements the right interface say for yet another database and everything will still work this pattern can be very useful for writing more testable code testing your generic database object is hard without actually touching a database but if you injected a fake database implementation you could test the wrapper with this delicate this is kind of what mock classes are doing for you this pattern actually makes me a little uncomfortable it isn't really the pattern's fault but my own experience I've bumped into a couple of coders in my life who thought this approach was a religion and thought you should inject all the things if the only use of a baseball bat you ever saw was it smacking you in the face it wouldn't be a surprise if you flinched watching the New York Yankees so injection kind of makes me flinch object-oriented coding started to come into its own in the 1980s at the time there were different languages out there experimenting with the right way of doing things and plenty of academic papers on the subject the first version of C plus plus was actually a transpiler converting C plus plus into C code before calling the C compiler the work in this space resulted in a bunch of tenants describing the right way to do things solid is an acronym that covers five of these governing principles the principles are single responsibility it should do only one thing the open closed principle you should be able to extend an object without mucking with its internals list gov substitution principle a harder way of saying duct typing interface segregation principle don't put stuff in an object that won't be used and the dependency inversion principle that says interacting objects should use an interface between them some of this stuff may seem a little obvious if you've done a lot of object-oriented coding already but it's obvious because of the work done historically that makes it so it is the work of several people the concepts in solid along with a bunch of others were in a paper by Robert C Martin in 2000 Martin is better known as Uncle Bob in the programming world and was one of the creators of the agile Manifesto a few years later Michael feathers munched it together in an easier to remember acronym those two don't get all the credit the list gov substitution principle is named after Barbara liskov who came up with it so it's a real amalgamation of effort the rest of this course uses solid to talk about what good object-oriented coding looks like all right let's dive into something solid well that sounds ill-advised doesn't it in the previous lesson I talked about whether to use an object-oriented approach in Python this lesson kicks off the solid principles the s in solid is the single responsibility principle it is stated as a class should have only one reason to change let's break that down what a class does is expressed through the methods it provides its responsibility if your class implements more than one task you're breaking the single responsibility principle and you should break your class up into multiple classes this is all about the separation of concerns let's look at an example in code consider this class that abstracts a file its interface includes a method for reading a file a method for writing a file one for compressing a file to zip format and one for decompressing from the zip format does this seem like a single responsibility yeah not really not all the file objects you create are going to need compressing and uncompressing only zip files do that's a sign that you're doing too many things in the class the solution is to break this up into more pieces instead of having a single file manager this module implements the same functionality as two different classes the file manager class abstracts the reading and writing of the class having the read and write methods from before while the zip file manager contains the compress and decompress methods I haven't done it here but you could imagine a method on zip file manager that returns a file manager object pointing to the uncompressed file that was ready for reading and writing you want to separate out your responsibilities because it means less to keep in your head while you're maintaining the class smaller chunks of code tend to be easier to test and debug this isn't just because they're smaller but because you can separate out expected Behavior for example if you think back to my bad file manager what does it mean to read or write to it if it's still compressed does the class Implement that or would it muck things up single responsibility doesn't mean only a single method you still want all the methods that make sense for the data on the class assuming you pick the right data abstraction the better file manager needs both the read and write methods but mixing in compress and decompress makes things messy fundamentally the file in zip file classes have different purposes and do different things one is for reading and writing a file the other is for compressing and decompressing that's not to say you couldn't come up with a better abstraction you could build a version of the zip class that only implements read and write decompressing and reading or decompressing and writing then compressing back when it's done Uncle Bob's paper on the topic tells a story where he was writing code for a multi-purpose printer originally he just had a printer class but maintaining the fax machine and scanning functionality in that class didn't make a lot of sense so instead he split it up into three different classes that's the s next up the O in solid
Original Description
This is a preview of a video course on Object-Oriented Design and SOLID principles. Knowing when and when not to use it, as well as guiding principles behind object-oriented design will help you write better code. You will also learn about the S in SOLID - The Single-Responsibility Principle (SRP).
This is a portion of the complete course, which you can find here:
https://realpython.com/courses/solid-principles-python/
The rest of the course covers:
- The Open-Closed Principle (OCP)
- The Liskov Substitution Principle (LSP)
- The Interface Segregation Principle (ISP)
- The Dependency Inversion Principle (DIP)
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Real Python · Real Python · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
A better Python REPL – bpython vs python interpreter
Real Python
Introducing large-type.com – A Utility Website
Real Python
Reading Hacker News Without Wasting Tons of Time
Real Python
Forward References and Python 3 Type Hints
Real Python
Using Sublime Text as your Git Editor
Real Python
Python Code Linting and Auto-Complete for Sublime Text
Real Python
Make your Python Code More Readable with Custom Exceptions
Real Python
Write Better Tests with Sublime Text's Split Layout Feature
Real Python
How to Use Sublime Text from the Command Line
Real Python
Rename Variables with Multiple Selection in Sublime Text
Real Python
Sublime Text Settings for Writing PEP 8 Python
Real Python
Write Cleaner Python with Sublime Text's Indent Guides
Real Python
Sublime Text Whitespace Settings for Python Development
Real Python
Function Argument Unpacking in Python
Real Python
Python Code Review: Debugging and Refactoring "Conway's Game of Life" + Automated Tests
Real Python
Using "get()" to Return a Default Value from a Python Dict
Real Python
A Python Shorthand for Swapping Two Variables
Real Python
Python Code Review: Refactoring a Web Scraper, PEP 8 Style Guide Compliance, requirements.txt
Real Python
Click & Jump to Test Failures from the Command Line (iTerm2)
Real Python
Setting up Sublime Text for Python Developers
Real Python
Sublime Text + Python Guide Overview
Real Python
Python Code Review: Adding Pytest Tests to an Existing Python Web Scraper
Real Python
Type-Checking Python Programs With Type Hints and mypy
Real Python
A Shorthand for Merging Dictionaries in Python 3.5+
Real Python
Python Code Review Flask Web Security Tutorial + Virtualenvs, requirements.txt
Real Python
My Python Code Looks Ugly and Confusing – Help!
Real Python
Setting Up a Programmer Portfolio/Developer Blog – How To Get Started
Real Python
Do I Need a GitHub/GitLab/Bitbucket Profile as a Developer?
Real Python
Programmer Portfolio – Example and Walkthrough
Real Python
How to Get Your 1st Speaking Gig at a Tech Conference
Real Python
How to Build Your Public Speaking Skills as a Developer
Real Python
The Object-oriented Version of "Spaghetti Code" is "Lasagna Code" ?!
Real Python
Setting up Sublime Text for Python Developers – Lesson #1
Real Python
Cool New Features in Python 3.6
Real Python
"is" vs "==" in Python – What's the Difference? (And When to Use Each)
Real Python
Emulating switch/case Statements in Python with Dictionaries
Real Python
Python Function Argument Unpacking Tutorial (* and ** Operators)
Real Python
What Code Should I Put On My GitHub/GitLab/BitBucket Profile?
Real Python
A Crazy Python Dictionary Expression ?!
Real Python
String Conversion in Python: When to Use __repr__ vs __str__
Real Python
Method Types in Python OOP: @classmethod, @staticmethod, and Instance Methods
Real Python
Optional Arguments in Python With *args and **kwargs
Real Python
Python Context Managers and the "with" Statement (__enter__ & __exit__)
Real Python
Installing Python Packages with pip and virtualenv / venv
Real Python
"For Each" Loops in Python with enumerate() and range()
Real Python
Python Code Review: LibreOffice Automation and the Python Standard Library
Real Python
Managing Python Dependencies With Pip and Virtual Environments – Lesson #1
Real Python
Python Tutorial: List Comprehensions Step-By-Step
Real Python
Leveraging Python's Implicit "return None" Statements
Real Python
What's the meaning of underscores (_ & __) in Python variable names?
Real Python
Python Data Structures: Sets, Frozensets, and Multisets (Bags)
Real Python
Writing automated tests for Python command-line apps and scripts
Real Python
How to find great Python packages on PyPI, the Python Package Repository
Real Python
Immutable vs Mutable Objects in Python
Real Python
PyPI vs Warehouse, the Next-Generation Python Package Repository
Real Python
pep8.org — The Prettiest Way to View the PEP 8 Python Style Guide
Real Python
My Experience at PyCon 2017 in Portland
Real Python
Pylint Tutorial – How to Write Clean Python
Real Python
"Reverse a List in Python" Tutorial: Three Methods & How-to Demos
Real Python
Python Refactoring: "while True" Infinite Loops & The "input" Function
Real Python
More on: LLM Foundations
View skill →Related Reads
📰
📰
📰
📰
Builder Story: Saymon and Core Care
Dev.to AI
AI-Powered Variance Narratives: Prompt Engineering for Solo Fractional CFOs
Dev.to AI
A Gen X entrepreneur closing their laptop at the end of a productive, shortened workday, ready to…
Medium · AI
Earning Technical Certifications in 5 Steps with AI Tools
Dev.to AI
🎓
Tutor Explanation
DeepCamp AI