关于操作符:python的__add__ 和 __concat__有什么区别?

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

python的标准操作符列表包括__add__(a, b)__concat__(a, b)。它们通常都由a + b调用。我的问题是,他们之间有什么区别?有没有一个场景会使用一个而不是另一个?在一个对象上定义两个对象有什么原因吗?

这是我在中找到方法的文档。

编辑:增加了奇怪的是,这是文件:

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.


如果您检查operator模块(add,concat)的源代码,您将找到这些函数的定义:

1
2
3
4
5
6
7
8
9
10
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

所以除了concat实际上需要一个序列类型之外,实际上没有什么区别。这两个函数都使用+运算符,其效果取决于添加的类型。

一般来说,使用operator模块在大多数情况下没有那么有用。当您需要传递一个执行操作的函数时,通常使用该模块,例如传递到诸如mapfilterreduce之类的函数。但通常,您可以直接使用+操作符。

对于下划线函数(__add____concat__来说,它们只是别名:

1
2
__add__ = add
__concat__ = concat

但这些当然与用于重载自定义类型的运算符的特殊方法无关。它们是与那些特殊方法同名的函数,可能是为了使它们看起来相似。但请注意,对象上没有特殊的__concat__方法。

但是,在自定义类型上实现__add__将影响操作员模块功能的工作方式,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> 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)

如您所见,operator.add将使用特殊方法Example.__add__的实现,但其原因是operator.add的实现只使用+操作符(该行为由特殊__add__方法明确定义)。


  • operator.__add__(a, b):返回a + b,用于ab号*。
  • operator.__concat__(a, b):返回ab序列的a + b

有什么区别?

例如,不能连接整数:

1
2
3
4
>>> 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)只是做a + b,因此它也在序列上工作。


根据文件,

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

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

接线员。添加(A,B):

它只会尝试执行a + b并给出结果。

如。

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

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

接线员uu concat_uuuuu(a,b):

在这里,它将检查a是否具有属性__getitem__。如果它没有__getitem__属性,则会引发异常,否则将尝试执行a + b

如。

在对数字执行此操作时,将引发异常。

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

当对两个字符串执行时,它执行字符串串联。

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