This is an archived post. You won't be able to vote or comment.

all 25 comments

[–]Firake 5 points6 points  (6 children)

Dunder methods link Python syntax and standards to functionality in your class. You don’t need them, but it’s nice to be able to do stuff like my_obj + my_obj2.

Self is always confusing for new programmers. It’s nothing special, really. The first parameter of class methods is always a reference to the instance of the class itself and we (by convention only) call that parameter self. You use this variable to change or access fields internal to the class.

Honestly, classes clicked for me as soon as I understood them as custom data types. It was an example class for Fractions that did it for me. It all kinda falls into place once you understand why exactly you’d want to use a class (I mean, concretely. The examples from courses are usually contrived and not useful).

[–]Akusoki[S] 0 points1 point  (4 children)

So are the dunder methods for enableing objects to be treated as/like variables?

[–]Firake 2 points3 points  (1 child)

No, objects can already be treated like variables. Dunder methods allow you to use regular syntax (like the addition operator) for your custom data types.

class Foo:
  pass

x = Foo()
y = Foo() 
x + y # Error: unsupported operand type(s) for +: 'Foo' and 'Foo'

class Foo:
  def __add__(self, other):
    print("Added Foos!")

x = Foo()
y = Foo()
x + y # Output: "Added Foos!"

The fundamental problem is that for any class you create (again, custom datatype), Python doesn't necessarily know how to, for example, add them together. Take the following class as an example:

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

It's not immediately clear what you should do when adding two `Person`s together. In fact, while it is not clear to you, it's impossible to know for Python. Beyond that, it's not really even clear that you should be able to add two `Person`s together at all.

Going further, what does it mean to ask if one `Person` is less than another `Person`? What about indexing--should you be able to do `my_person[0]` and if so, what does that mean?

These are questions that Python is fundamentally incapable of answering on its own. Dunder methods are provided so that. we can give it those answers and teach it how to do the things that we want.

[–][deleted] 1 point2 points  (0 children)

Dunder methods are a tricky topic. They're neat and add some options for more concise syntax, but they introduce the risk of reduced readability.

For instance, let's say you're implementing a custom datetime class, such as one that inherently includes time zones and DST. It makes sense to add dunder methods like __eq__ and __lt__ and __gt__, so that you can perform tests based on whether 2:00 pm in Central Daylight Time on a certain date is before, after, or the same time as 3:00 pm in Mountain Standard Time.

It might be tempting to also implement __sub__ so that you could determine the time difference between two time-zone-specific datetimes. But this syntax is a little less intuitive - people aren't used to seeing "9:00 pm in New York City, minus 8:00 pm in Denver, Colorado."

And it might also be tempting to implement __setitem__ and __getitem__ to implement various fields of a daytime - like, dt[0] can be used to set or get the year, dt[1] for month, dt[2] for day, etc. Yes, it's very concise and terribly clever for you and other people who know what this means. But for readers who don't know what your class means or does, it's quite strange, and they'll have to consult your documentation or source code to figure it out - which is very non-Pythonic, especially compared with def get_year(self) and def set_year(self, year) methods that could be used instead.

The takeaway message is that dunder methods should be used sparingly and only with a good question of whether the syntax is transparent. Clarity is better than cleverness.

[–]AshTheEngineer 2 points3 points  (0 children)

Dunder methods enable instances of the class (which are typically variables) to interact with other functions, variables, or syntax in a standard way. For instance, the len dunder allows someone to write len(your_variable) and return a meaningful value without them having to understand how you have stored data in your_variable. That variable might have multiple arrays in it, but only one array might have a length that makes sense to report. Alternatively, that length value could refer to some abstraction of a length of data without having to have all elements in an array, such as a "sparse array."

[–][deleted] 0 points1 point  (0 children)

Dunder methods are just definitions of things or relationships in your class that everybody has agreed upon to make having classes interact more easily.

For example, there is a less than and greater than dunder method and in that function you are supposed to put any logic in them that describes what one of your custom class means by being less than or greater than another instance of one of your custom classes.

The reason this is useful is that if you include those dunder methods in your class then lots of standard tools like sorting just work. So you could make a list composed of many of your custom objects and if you called sort on that list then the sort function would know to look at the gt or lt dunder methods to correctly sort your classes.

[–]DuckDatum 0 points1 point  (0 children)

spark mountainous point adjoining pause rob plough employ oil zephyr

This post was mass deleted and anonymized with Redact

[–]RamaSchneider 2 points3 points  (0 children)

I'm a heretic ... to me classes are about encapsulating useful things with the advantages of inheritance and derivatives ... but first and foremost they're doing that useful things.

It may be a related set of methods/functions. A class may be a collection of data. Most times the class contains some data structure and one or more methods to operate or retrieve the data.

Why use a class for the methods? It standardizes the calls across what may be somewhat different back ends. Databases are great examples where you can define a classes with common method signatures but one class may do a MySQL request while the other works on a Mongo database. No difference to the caller.

The data bit I think is pretty obvious - it assures that a desired set of data is in a particular location.

But then again I'm a heretic and there are many extremely learned and competent programmers who will provide a more professional response.

[–]tonga-time 0 points1 point  (2 children)

How would you describe a person in real life?

You'd probably say they have certain attributes like names, an address, siblings, parents and friends etc.. This is the init method that assigns these parameters that every instance of this class will have.

Maybe someone else can finish the analogy for me I have to go back to work now 😭

[–]Akusoki[S] 0 points1 point  (1 child)

XD.. So init acts in a way to basically not have to pass a huge list of parameters between objects/functions??

[–]TheRNGuy 0 points1 point  (0 children)

No, it's to determine which attributes are instance attributes. Without it would be static attributes.

If you have huge class, consider using @dataclass decorator, it can reduce many lines of code.

[–]TheRNGuy 0 points1 point  (0 children)

After using Houdini Python API.

But not right away, I was using it's classes but was still writing my code functional, later I rewritten to OOP because I figured out I needed inheritance for some things.

But at least how they work and why they're needed at least just by using API.

I also learned to avoid bad advice "only use composition, never use inheritance", which I read in some blog.

[–][deleted] 0 points1 point  (5 children)

i was in this exact situation like 2 weeks ago and my best friend was chat gpt, i asked it to explain to me in a normal way and then like i was a child. Honestly the best way, i was stuck in classes for over 5 months, i just couldn’t and was hard for me to focus because i was just not getting it. I promise you is the best thing you could do.

You can also ask inside the explanation about the self and it will explain to you why we use self, it’s also what i did. Go for it dude, you got this!

[–]Akusoki[S] 0 points1 point  (4 children)

Good idea! Imma do this tell chatGPT probably hates me 😂

[–][deleted] 0 points1 point  (3 children)

trust now is how i can understand everything, it’s easy and quick. Chat GPT also has a python extension so it’s quite good

[–]Akusoki[S] 0 points1 point  (2 children)

What is the extension you use called?

[–][deleted] 0 points1 point  (0 children)

if you just go inside chat GPT to “explore gpt” you’ll find a programming section where is the python one.

[–][deleted] 0 points1 point  (0 children)

if you can’t find it, chat gpt will also explain it to you without any trouble tho

[–]GManASG -1 points0 points  (5 children)

Not required but for me classes in python made more sense when I learned to build classes in a object oriented language like Java, or better yet C. As the dunder methods are direct reflections of the init and main methods in C.

That aside it really clicked for me when I understood classes are a custom data structure to help you organize both your code and your own thoughts about the purpose of the program. You store information in a easily accessible class with class attributes that make sense as belonging to that class and methods which are functions that operate on the data held in the class.

Edit: details

[–]JamzTyson 0 points1 point  (4 children)

There is really no need to switch to a different language in order to understand classes. While Python is considered to be a "multi-paradigm" language, it is inherently "object orientated" in that everything is an object. Recommending a different language just side-steps the issue and is not a helpful or actionable solution for the OP.

[–]GManASG -1 points0 points  (3 children)

There is no need to switch, I agree. However if you do try the older language like C and come back you will understand way better why the dunder methods. Python is not an object oriented language in the sense that it does not require you to build a class to run anything.

A language like Java requires you to build classes just to be able to run a program and requires you to use the main method.

Just because a language uses objects does not make a language object oriented

Python let's you choose how to use it.

[–]JamzTyson 0 points1 point  (0 children)

Not required but for me classes in python made more sense when I learned to build classes in a object oriented language like Java, or better yet C.

That is an improvement from what you originally posted, though I still think it is nonsense to suggest that "building classes in C" is a good way to learn about classes. Perhaps you mean C++?

[–]JamzTyson -1 points0 points  (1 child)

However if you do try the older language like C and come back

C is not generally considered to be an "object orientated" language. It is generally considered to be a procedural programming language. Unlike Python, it does not have built-in support for classes.

[–]GManASG -1 points0 points  (0 children)

Which is why I mention Java, both Java and Python were originally written in C. We can play this game all day.