Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Python's __add__ and __concat__?

The list of Python's standard operators includes both __add__(a, b) and __concat__(a, b). Both of them are usually invoked by a + b. My question is, what is the difference between them? Is there a scenario where one would be used rather than the other? Is there any reason you would define both on a single object?

Here's the documentation I found the methods mentioned in.

Edit: Adding to the weirdness is this documentation:

Finally, sequence types should implement addition (meaning concatenation) and multiplication (meaning repetition) by defining the methods __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() and __imul__() described below; they should not define __coerce__() or other numerical operators.

like image 624
ArtOfWarfare Avatar asked Jun 18 '15 19:06

ArtOfWarfare


2 Answers

If you check the source for the operator module (add, concat), you will find these definitions for those functions:

def add(a, b):
    "Same as a + b."
    return a + b

def concat(a, b):
    "Same as a + b, for a and b sequences."
    if not hasattr(a, '__getitem__'):
        msg = "'%s' object can't be concatenated" % type(a).__name__
        raise TypeError(msg)
    return a + b

So there is actually no difference except that concat actually requires a sequence type. Both functions use the + operator which effect depends on the types you add.

In general, using the operator module is not that useful most of the time. The module is mostly used when you need to pass a function that performs an operation, for example to functional functions like map, filter, or reduce. But usually, you can just use the + operator directly.

As for the underscore functions (__add__ and __concat__), these are just aliases:

__add__ = add
__concat__ = concat

But those are of course not related to the special methods used to overload operators for custom types. They are functions that match the same name as those special methods, probably to make them appear similar. Note that there is no special __concat__ method on objects though.

Implementing __add__ on a custom type will however affect how the operator module functions work, for example:

>>> class Example:
        def __init__ (self, x):
            self.x = x
        def __repr__ (self):
            return 'Example({})'.format(self.x)
        def __add__ (self, other):
            return Example(self.x + other.x)

>>> a = Example(2)
>>> b = Example(4)
>>> operator.add(a, b)
Example(6)
>>> a + b
Example(6)

As you can see, operator.add will use the implementation of the special method Example.__add__; but the reason for that is that the implementation of operator.add just uses the + operator (which behavior is explicitely defined by the special __add__ method).

like image 170
poke Avatar answered Sep 17 '22 01:09

poke


  • operator.__add__(a, b): Return a + b, for a and b numbers *.
  • operator.__concat__(a, b): Return a + b for a and b sequences.

What's the difference?

For example, you can't concatenate integers:

>>> operator.__concat__(2,3)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'int' object can't be concatenated

  • actually __add__(a, b) just does a + b, hence it works on sequences too.
like image 44
fferri Avatar answered Sep 18 '22 01:09

fferri