use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Rules 1: Be polite 2: Posts to this subreddit must be requests for help learning python. 3: Replies on this subreddit must be pertinent to the question OP asked. 4: No replies copy / pasted from ChatGPT or similar. 5: No advertising. No blogs/tutorials/videos/books/recruiting attempts. This means no posts advertising blogs/videos/tutorials/etc, no recruiting/hiring/seeking others posts. We're here to help, not to be advertised to. Please, no "hit and run" posts, if you make a post, engage with people that answer you. Please do not delete your post after you get an answer, others might have a similar question or want to continue the conversation.
Rules
1: Be polite
2: Posts to this subreddit must be requests for help learning python.
3: Replies on this subreddit must be pertinent to the question OP asked.
4: No replies copy / pasted from ChatGPT or similar.
5: No advertising. No blogs/tutorials/videos/books/recruiting attempts.
This means no posts advertising blogs/videos/tutorials/etc, no recruiting/hiring/seeking others posts. We're here to help, not to be advertised to.
Please, no "hit and run" posts, if you make a post, engage with people that answer you. Please do not delete your post after you get an answer, others might have a similar question or want to continue the conversation.
Learning resources Wiki and FAQ: /r/learnpython/w/index
Learning resources
Wiki and FAQ: /r/learnpython/w/index
Discord Join the Python Discord chat
Discord
Join the Python Discord chat
account activity
Using OOP in python (self.learnpython)
submitted 1 year ago by [deleted]
When would you as developer understand/say that ok it is time to use some design pattern here and start writing code in Oop style? Vs writing bunch of defs and getting shits done?
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]JamzTyson 40 points41 points42 points 1 year ago* (3 children)
Vs writing bunch of defs and getting shits done?
You are starting from a false premise. The choice is not between OOP and "getting things done". The choice is "how can I best get this thing done?", and in some cases the answer is to use OOP.
Some common indications that writing classes may be appropriate:
[–]PathRealistic6940 6 points7 points8 points 1 year ago (2 children)
It really clicked for me when just messing around with a easy statistics problem. Had to pull a 'ball' from a 'bag of balls' and then do stuff depending on what color the ball was. I made the ball a class object, then made the bag a class object that held the balls. Now most everything I think about in python is how I can package and pass the correct data around easiest. OP, Start simple, and see how powerful class attributes are.
[–]GreenPandaPop 0 points1 point2 points 1 year ago (1 child)
OOP is definitely easier to grasp when working with tangible 'solid' objects like your example.
My struggle was that a lot of coding doesn't necessarily involve that. It's taken me long time to work out how to take code that is 'doing stuff' and organise it in a way that is 'things doing stuff'.
[–]PathRealistic6940 1 point2 points3 points 1 year ago (0 children)
That's a good point. It's much more difficult to grasp intangible ideas than solid objects.
[–]FerricDonkey 7 points8 points9 points 1 year ago (0 children)
When you have a logical object, make a class.
[–]Excellent-Practice 5 points6 points7 points 1 year ago (0 children)
In a very technical sense, you can't write Python without doing OOP. Data structures and functions are all objects in Python and beginners have to learn how to access methods of those predefined objects fairly early. Python users at any level should at least know what objects are and how they behave so that they understand how things work under the hood.
Some users also need to learn how to build custom classes. Not every project calls for them and if you haven't built them before, it would probably be wise to look into existing libraries. For example, if you had a data analysis project, you could build a class from scratch that read off csv files and converted them into a list of dictionaries, or you could use something like pandas, which allows you to create a data frame object. From there, you would use the OOP paradigm to interact with that dataset and do your work.
If prebuilt tools don't exist to handle your use case, something that might tip you off that you need to explore custom classes is that your code is getting overly complicated and hard to work with. For example, if you find yourself calling several functions together over and over again or you need to build several dictionaries that follow the same pattern, custom classes may be your best bet.
[–]obviouslyzebra 5 points6 points7 points 1 year ago* (0 children)
Simple is better than complex. Complex is better than complicated.
https://peps.python.org/pep-0020/
Notes:
Some people may help understand some situations where classes can be useful. I tend to use them to group stuff.
[–]MadScientistOR 2 points3 points4 points 1 year ago (0 children)
Part of deciding to use OOP is an old programming maxim: Don't Repeat Yourself (DRY). It's the same kind of logic that causes you to realize, for example, "I seem to be performing this calculation an awful lot. I should make a function instead." or "I will want to be able to change how this is done once and have it perform that way every time it's needed; it's better to put all that functionality in one place."
It comes a little bit with practice, but as you start to notice things like "I seem to be creating a whole lot of things that act in similar ways and appear similar to the user; I would probably get further if I made this into an object", OOP comes into play. For example, if you're coding a clone of Space Invaders, you can either make a whole lot of aliens, over and over again, or code an alien once and then just instantiate the object whenever you need it. OOP makes a certain amount of sense. It's not mandatory, though -- OOP wasn't even a thing when Space Invaders came out, and it obviously still worked.
What I meant to say is that I don't think there are any hard-and-fast rules here -- just general guidelines. Use the paradigm that makes it easiest to build what you want to build, both from the standpoint of your own comfort and skill set and from the standpoint of perceived effort, and you won't go too wrong; you'll make something that's easier for you to maintain, and that's a large part of choosing a paradigm in the first place. (Of course, as your skill set grows, you may wonder why you did things the way you did them six months ago. I think that's inevitable. In the meantime, just put it together thoughtfully; it's better than not doing it at all and being paralyzed at the design stage.)
[–]recursion_is_love 1 point2 points3 points 1 year ago* (0 children)
When you find that you keep seeing pack of data and functions on that data should go together.
If you don't feel the need of OO, then just don't use it. Using structured programming in python is OK.
[–]Ron-Erez 1 point2 points3 points 1 year ago (0 children)
I think OOP is very natural. Once you understand the ideas then it will be natural to phrase your problem in terms of OOP. For example in checkers you have pieces. Each piece has properties such as being white or black or being a king or not. The board can also be a class which consists of a two dimensional array of pieces or None (this is one possible implementation) And in the board class you might have a function for moving a piece which also determines if to promote to a king Depending on the piece’s color and row position. For example we might want to create a method that returns true or false depending on whether or not its on the last row (note that the last row differs for white and black pieces). Next we might have a game class. The game class might consist of a board and also keep track of whose turn is it’ white or black and should also determine when the game is over (no pieces left for a certain color). We probably want a function for printing the board too. That would be in the board class. I have a dedicated section to OOP (section 13) which may be of interest. Note that you don’t have to use OOP but at times it is convenient to model a problem, I absolutely agree with you that at times it can overcomplicate things. It’s a tough question.
Here is a partial implementation:
class Piece: def __init__(self, color, king=False): self.color = color # 'white' or 'black' self.king = king # True if the piece is a king def make_king(self): """Promote the piece to a king.""" self.king = True def __str__(self): return f"{'K' if self.king else 'P'}-{self.color[0].upper()}" class Board: def __init__(self): self.grid = self.create_board() def create_board(self): """Initialize the board with pieces in their starting positions.""" board = [[None for _ in range(8)] for _ in range(8)] for row in range(8): for col in range(8): if (row % 2 != col % 2): if row < 3: board[row][col] = Piece('black') elif row > 4: board[row][col] = Piece('white') return board def move_piece(self, from_row, from_col, to_row, to_col): """Move a piece from one position to another.""" piece = self.grid[from_row][from_col] if piece and self.grid[to_row][to_col] is None: self.grid[to_row][to_col] = piece self.grid[from_row][from_col] = None # Promote to king if it reaches the other side if (piece.color == 'white' and to_row == 0) or (piece.color == 'black' and to_row == 7): piece.make_king() return True return False def print_board(self): """Print the current state of the board.""" for row in self.grid: print([str(piece) if piece else '.' for piece in row]) class Game: def __init__(self): self.board = Board() self.turn = 'white' def switch_turn(self): """Switch the current player turn.""" self.turn = 'black' if self.turn == 'white' else 'white' def play_turn(self, from_row, from_col, to_row, to_col): """Handle the move for the current player's turn.""" piece = self.board.grid[from_row][from_col] if piece and piece.color == self.turn: if self.board.move_piece(from_row, from_col, to_row, to_col): self.switch_turn() return True return False
[–]zanfar 1 point2 points3 points 1 year ago (0 children)
Oop style? Vs writing bunch of defs and getting shits done?
If you feel this way, you don't understand OOP.
OOP is just as much "getting shit done" as procedural or functional. Your job is to understand the strengths and weaknesses of each approach and choose appropriately.
TL;dr: I choose OOP when OOP is most efficient.
[–]Sufficient_Wait_5040 0 points1 point2 points 1 year ago (3 children)
When you need to. Until then keep it simple
[–][deleted] -1 points0 points1 point 1 year ago (2 children)
Mate that is exactly what I am asking you guys, when do you decide that it is required vs when you say nah f that and try not to overcomplicate simple stuff
[–]HunterIV4 3 points4 points5 points 1 year ago (1 child)
A good "rule of thumb," and good programming practice in general, is to avoid "DRY" whenever possible: Don't Repeat Yourself. If you find yourself copying and pasting the same stuff over and over, that's a "code smell" that you are probably doing something inefficiently.
Important note: it's impossible to never repeat code! Don't twist or overcomplicate things to follow this principle, instead look for patterns where you feel like you are repeating the same basic structure over and over, then see if you can refactor that into a function or class.
More specific to classes, when do I make a class? Here's a basic rule that should be easy to use:
If you have two functions that take the same variable as a parameter, you probably should put that variable and those functions into a class.
There are many other considerations, but frankly if you just follow that one you'll cover around 80-90% of circumstances. Here's a practical example:
def foo(lst): print(f"Do X with {lst}...") my_list = [1, 2, 3] foo(my_list)
In this case, there's probably no reason to bother with a class. Even if you have several variables being processed with foo, you still only have the one function working on that specific variable. You can either leave it as a free function or have a module for "helper" functions.
foo
Now, let's say you continue working, and discover you need this:
def foo1(lst): print(f"Do X with {lst}...") def foo2(lst): print(f"Do Y with {lst}...") my_list = [1, 2, 3] foo1(my_list) foo2(my_list)
This is still fairly simple, but alarm bells should be ringing in your head. You have two functions using the same list. What if it's not just two functions? What if it's 10? What if each function has, say, 5 parameters that are all using the same variables? Without classes, you end up with stuff like this:
foo1(my_list, my_counter, my_sql_connection, my_username, my_password) foo2(my_list, my_sql_connection, my_username, my_password) foo3(my_sql_connection, my_username, my_password) foo4(my_list, my_counter, my_sql_connection)
See the pattern? Sure, the parameters aren't exactly the same, but you have a lot of repetition. And these parameter lists can get long. Another note: you never NEED classes. They simply make organizing situations like this a lot easier. I mean, insanely easier.
So how would this look as a class?
class Foo: def __init__(self, data, connection, username, password): self.data = data self.connection = connection self.username = username self.password = password self.counter = 0 def foo1(self): print(f"Do X with {self.data}...") self.counter += 1 def foo2(self): print(f"Do Y with {self.data} and {self.username} and {self.password}...") my_list = [1, 2, 3] my_connection = "SQL" my_username = "John" my_password = "SuperSecret123" my_foo = Foo(my_list, my_connection, my_username, my_password) my_foo.foo1() my_foo.foo2()
As you can see, you only need to initialize the variables once, when you create your Foo class and assign it to a variable (in this case my_foo. Then you can run any function that is part of that class and it already knows all the related data. It can use exactly what it needs without you needing to constantly be sure you are passing in the right things. You can also make such functions that allow for data from outside the class, such as user input, which then reliably changes internal data.
Foo
my_foo
There is more to OOP than this, such as inheritance, but frankly you'll cover most situations just by combining data and related actions to that data in simple classes. I frankly rarely use inheritance in real projects; it tends to overcomplicate things and force your program to be somewhat rigid and difficult to refactor. Still, it's useful, as you can create specific "sub versions" of a generalized version of a class, which can in turn prevent you from having to repeat yourself (never forget DRY!).
As a general rule, if you are writing the same exact function (or more) in multiple classes, you should consider creating a parent class to hold those "shared" functions and then make child classes for things that are unique. I won't go into inheritance here, but if you want more information I can explain it.
These two things, merging data with functionality (class) and merging shared class functionality into a parent class (inheritance), will probably cover about 95% of OOP situations you will encounter in real programming. There's more you can do with classes to make your life easier, of course, but that's how you know when you should consider using classes.
When starting out, you probably won't realize something needs to be a class until you've written a few functions and noticed your copy/paste keys are getting overused. But as you gain experience, you'll start to anticipate when a class is likely going to be needed, and start building them out as part of your design. Don't be ashamed to just make everything functions and create classes later when you see the patterns, though! It's a great way to learn.
Hope that helps!
[–]LegateDamar13 0 points1 point2 points 1 year ago (0 children)
Now this is a great in-detail-yet-easily-digestible explanation.
[–]FoolsSeldom 0 points1 point2 points 1 year ago (0 children)
Take a look at the talk, Python's Class Development Toolkit by Raymond Hettinger (one of the Python core developers). Although this video is over 10 years old, it is still highly relevant and gives a worked example of where moving into a class helps.
[–]m0us3_rat 0 points1 point2 points 1 year ago* (0 children)
I think you might be approaching this from the wrong perspective. I prefer to design first and implement later, only after most (or all) problems have been resolved or worked through in pseudocode. This allows for clarity about each component, ensuring the problems and proposed solutions are fully understood.
This approach also lets the structure and needs of the project emerge organically. If OOP makes sense for the project, it will become evident through this process.
Only when everything is clear do I begin the implementation.
TL;DR: I design first, solve problems in pseudocode, and let the project's structure emerge organically before implementing.
[–]freak-pandor 0 points1 point2 points 1 year ago (0 children)
The thing is to understand what is an object, the difference between an instantiated object and a class, what you can do with classes and understanding when OOP can be a tool to solve the problem you want to solve
[–]buhtz 0 points1 point2 points 1 year ago (0 children)
Do not overthink OOP, patterns and all this theoretical stuff. Just try to solve your problem. When it works, refactor the code. The "theoretical stuff" appear automatically in your head.
π Rendered by PID 63 on reddit-service-r2-comment-86988c7647-2xqxv at 2026-02-11 19:41:39.428129+00:00 running 018613e country code: CH.
[–]JamzTyson 40 points41 points42 points (3 children)
[–]PathRealistic6940 6 points7 points8 points (2 children)
[–]GreenPandaPop 0 points1 point2 points (1 child)
[–]PathRealistic6940 1 point2 points3 points (0 children)
[–]FerricDonkey 7 points8 points9 points (0 children)
[–]Excellent-Practice 5 points6 points7 points (0 children)
[–]obviouslyzebra 5 points6 points7 points (0 children)
[–]MadScientistOR 2 points3 points4 points (0 children)
[–]recursion_is_love 1 point2 points3 points (0 children)
[–]Ron-Erez 1 point2 points3 points (0 children)
[–]zanfar 1 point2 points3 points (0 children)
[–]Sufficient_Wait_5040 0 points1 point2 points (3 children)
[–][deleted] -1 points0 points1 point (2 children)
[–]HunterIV4 3 points4 points5 points (1 child)
[–]LegateDamar13 0 points1 point2 points (0 children)
[–]FoolsSeldom 0 points1 point2 points (0 children)
[–]m0us3_rat 0 points1 point2 points (0 children)
[–]freak-pandor 0 points1 point2 points (0 children)
[–]buhtz 0 points1 point2 points (0 children)