Python的__add__和__concat__有什么区别?

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

Python 的标准运算符列表包括 __add__(a, b)__concat__(a, b)。它们都通常由 a + b 调用。我的问题是,它们之间有什么区别?是否存在使用一种而不使用另一种的情况?您是否有任何理由在单个对象上定义两者?

这里是documentation我找到的方法

编辑:更奇怪的是 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.

  • operator.__add__(a, b): Return a + b, 对于 ab numbers *.
  • operator.__concat__(a, b):Return a + b 用于 ab 序列 .

有什么区别?

例如,您不能连接整数:

>>> 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, concat) 的源代码,您将找到这些函数的定义:

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 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。但通常情况下,您可以直接使用 + 运算符。

至于下划线函数(__add____concat__),这些是 just aliases:

__add__ = add
__concat__ = concat

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

在自定义类型上实现 __add__ 然而会影响运算符模块函数的工作方式,例如:

>>> 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) Return a + b, for a and b numbers.

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

operator.__add__(a, b):

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

例如

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

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

operator.__concat__(a, b):

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

例如

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

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

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

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