简体   繁体   中英

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.

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

  • actually __add__(a, b) just does a + b , hence it works on sequences too.

As per docs,

operator.__add__(a, b) Return a + b, for a and b numbers.

operator.__concat__(a, b) Return a + b for a and b sequences.

operator.__add__(a, b):

It will just try to perform a + b and give the result.

Eg.

operator.__add__(1,2)  # performs 1 + 2
3

operator.__add__('a','b') # performs 'a'+'b'
'ab'

operator.__concat__(a, b):

Here, it will check if a has attribute __getitem__ . If it does not have __getitem__ attribute it raises an exception otherwise then try to perform a + b .

Eg.

On performing this operations on numbers, it will raise an exception.

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

When performed on two strings, it perform string concatenation.

operator.__concat__('a','b')
'ab'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM