Avoid These BAD Practices in Python OOP

preview_player
Показать описание
In this video, I’ll uncover common bad OOP Python practices and show you how to keep your code clean and maintainable. Learn why you should replace unnecessary classes with functions, use modules instead of classes with only static methods, and flatten deep inheritance hierarchies.

🎓 Courses:

👍 If you enjoyed this content, give this video a like. If you want to watch more of my upcoming videos, consider subscribing to my channel!

Social channels:

👀 Code reviewers:
- Yoriz
- Ryan Laursen
- Dale Hagglund
- Kit Hygh
- Alexander Milden
- Bean

🔖 Chapters:
0:00 Intro
0:11 #1 A Function Masquerading as a Class
1:53 #2 A Module Masquerading as a Class
4:37 #3 Complex Inheritance structures
7:51 #4 Not Relying on Abstractions
11:27 #5 Ignoring Encapsulation
15:34 #6 Excessive Use of Getters and Setters
17:40 #7 Heavily Relying on Mixins
22:50 Final thoughts

#arjancodes #softwaredesign #python

DISCLAIMER - The links in this description might be affiliate links. If you purchase a product or service through one of those links, I may receive a small commission. There is no additional charge to you. Thanks for supporting my channel so I can continue to provide you with free content each week!
Рекомендации по теме
Комментарии
Автор

Regarding functions masquerading as a class: I once found a YouTube video in which the presenter said, "If a class contains 2 methods and one of them is __init__ it probably isn't a class". Which is effectively what Arjan said of his DataLoader class.

apmcd
Автор

The difference between getters/setters in Java and Python is that in Java, if you don't use get/set and make the member itself public, you cannot change that in the future: you're stuck with a public member forever as part of the interface. In Python, you can start with a public member, but if you want to refine the behaviour later, you can make it private and add a property. The interface doesn't change for users.

maleldil
Автор

Man I love these “slashing over engineered OOP cruft into nice little functions videos” 😂

lunalect
Автор

I really enjoy Arjan code content. I found this channel late 2022 and it's helped me deeply. A lot of time when you are being taught clean Code, they make it seem like OOP is the way to go. But obviously as Arjan has pointed out, in python, there are times when you are better off with a module or with just functions.

yickysan
Автор

Great video! I have a request: could you create a follow-up video explaining when it makes sense to move from using just functions to adopting OOP, particularly when you should start incorporating methods (not just properties) in your classes?

mdanish
Автор

Another excellent presentation, Arjan! I've recommended it to our team as a good refresher. Some of your refactoring also was a good demo of dependency inversion. SRP definitely is the single (pun intended) most important guide star I stress to my colleagues - and to refactor, repeatedly and brutally, until you almost giggle because your code is so concise, readable and beautiful. Which means it's most likely also much more maintainable and reusable, perhaps even in ways you haven't planned for.

MikeCorvin-xp
Автор

So, a lot of these focus on people using classes where they should perhaps use something else, like functions & modules, which is valid, but something I see quite a lot is people using something else when they should actually use a class. For example, using a dictionary to structure complex, nested data when that data structure is known to the developer at compile (write) time, like requests with a known return structure and config files where I feel like you as the developer should really be prescribing how it is structured. So instead of having to hunt around a code base to find what keys are being accesed, classes allow for a much more declarative way of defining how the data should be structured. Another, albeit rarer example, is a module with a set of functions and a global variable that the other functions are reading and updating. Dont do that, please use a class.

thomasroberts
Автор

I think that I suggested to you in the discord the bad practice of a class only containing static methods. Really happy to see that it got included in a video aha 😀

loic
Автор

Not entirely OOP related, but rather general python related.

Whenever I am refactoring or dealing with bug fixes or new features I find myself dreading methods that return a tuple of objects. Most of the time this is only 2 different things, which isn't going to be too problematic. But if there's more than 2 elements in a tuple, especially if some of them are of the same type, this will soon become problematic. Sure, we can use (e.g) `mypy` to check for types, but if there's multiple elements of the same type, these types of checks won't find the error in the intent of the code (though tests should do). So I find myself then creating data classes to make sure these things are handled correctly.
And while on the other hand, the underlying issue might have to do with poor design, sometimes the coupled natured of the code doesn't allow for an easy fix for this within the confines of the current maintenance task. Other times even changing the return type could be problematic.

SangaPommike
Автор

One of the eye openers for me was tarting to think domain centric, so thinking of what aspect you're trying to represent in the real world and then copy that in the code. So if you do a library system, the book may be objects, but checking in and out could be functions, rather than an object. Doing this made my code cleaner and more robust

barmus
Автор

FunctionClass: a class with a lowercase verb describing the core operation, which is implemented in the __call__ method of it’s metaclass, and invariant operations in static methods of the main class, named as adverbs, nouns or qualifiers that compose with the class’s verb name.

Usage looks like:

from utils import crop

crop(img)
crop.with_margins(img)
crop.without_headers(img)
crop.as_png(in)
crop.fit_to_page(img, page)

kevinpham
Автор

17:12, you need to learn ctrl+d whilst selecting some text, it will create multiple cursors enabling you easier editing

WilliamWatkins-oz
Автор

Thanks for sharing re: Mixin. I like how you keep coming back to what is simple, effective and easy to understand.

thisoldproperty
Автор

The second is not completly correct, I'm a lazy, and want to import with autocomplete and forget about module name, actually second case, it's if I have a few methods with the same name

nickolayfetlistov
Автор

3:36 classes should have instances

6:46 Proceeds to use Enum

kaskilelr
Автор

13:57 AI caught stealing our money in 4k

Stabbles
Автор

Love it! Anything to remove unecessary oop is always welcome! Great examples.

ssmith
Автор

I love your OOP stuff/mindset. It changed my life.

hoseynamiri
Автор

Composition over inheritance! My old C++ job had a load of code that was at least 10 levels deep of inheritance on embedded code. Debugging and reasoning was impossible to learn, you had to have grown up with it.
Superb video!
And of course, don't forget that sometimes these bad practices are the right tool for the job, it's just rare. A good example is _global_, it's almost always bad apart from the rare time when it isn't (e.g. logging library logger mapping) but you must be very aware of the caveats (e.g. they're process local, not truly "global.")

DrGreenGiant
Автор

I would suggest another topi to cover Arjan: "underscores in Python"

marcinx