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.
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).
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
__add__(a, b)
just does a + b
, hence it works on sequences too.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With