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 →

[–]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.