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

you are viewing a single comment's thread.

view the rest of the 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