dcreager.net

Which method is called for a binary operator?

In Python, binary operators are generally syntactic sugar for a call to a corresponding “dunder” (double underscore) method. For instance, ‘x + y’ (usually) desugars into

type(x).__add__(x, y)

But there's more to the story, because either type (type(x) or type(y)) should have a chance to specify the behavior, and because subclasses should have a chance to override the behavior of a superclass.

To allow the rhs to specify the behavior, there is also a “reflected dunder” method for each operator (__add____radd__). (If a type wants an operator to be symmetric, it will use the same implementation for both the dunder and the reflected dunder.)

The decision tree is not that complex, but it is specified piecemeal in the language reference. Piecing it together, you get:

  • If the type(y) is a (proper) subclass of type(x), and it provides a different implementation of the reverse dunder, use that. (So even if the subclass instance is on the rhs, it has a chance to override the behavior.)
  • Otherwise, if type(x) implements the dunder, use that.
  • Otherwise, if type(x) and type(y) are different types, and type(y) implements the reverse dunder, use that.

§3.3.8 Emulating numeric types [Python language reference]

» Languages » Python