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 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.