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.
根据你链接到的文档,一个是数字,一个是序列
注意,__concat__不是像__add__那样的"神奇方法"是:docs.python.org/2/reference/datamodel.html
除了名字有什么不同吗?
@乔恩沙普-你为什么说一个是"魔法方法",另一个不是?这是一个官方术语吗?我认为这只是人们编造的一个术语,因为在口头交谈中提到"magic"比"underline-underlineunderline-underline"更容易说出。另外,在查看您链接到的文档时,我发现了一个更让人困惑的引用。我编辑了我的问题,把它包括进去。
@兵法魔术法是指江户一〔2〕双强调双方实现实际阶级行为的方法,例如江户一〔3〕是解决江户一〔4〕的。为什么那句话让你困惑?它只是告诉你,两个序列的__add__通常应该端到端地连接它们。
@"魔法方法"正式称为"特殊方法",指的是可以为类型实现的方法,为运算符和其他语法特性提供内置功能。一般来说,双下划线方法只受名称管理的影响,因此有时也用于私有成员。
@Jonrsharpe——好吧,所以重要的一点是,__concat__实际上没有在任何对象上定义——这就是为什么你说它不是一个神奇的方法。如果你发表了一个答案,说明我的困惑主要来自于使用与magic方法名称相同的方法名称的operator模块,那么我接受这个答案。
@《战争的艺术》我在回答《以东公约》(8)时对《以东公约》(1)的特殊方法作了更多的扩展,希望它能澄清一切。
如果您检查operator模块(add,concat)的源代码,您将找到这些函数的定义:
1
2
3
4
5
6
7
8
9
10def 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模块在大多数情况下没有那么有用。当您需要传递一个执行操作的函数时,通常使用该模块,例如传递到诸如map、filter或reduce之类的函数。但通常,您可以直接使用+操作符。
对于下划线函数(__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__方法明确定义)。
模块用于运算符通过reduce()
@Mescalinum that's what I wrote,"The module i s mostly used when you need to pass a function that performs an operation."
好吧因为功能编程很酷
@Mescalinum I added some functional examples,just for you;]
operator.__add__(a, b):返回a + b,用于a和b号*。
operator.__concat__(a, b):返回a和b序列的a + b。
有什么区别?
例如,不能连接整数:
1
2
3
4>>> operator.__concat__(2,3)
Traceback (most recent call last):
File"", line 1, in
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
5operator.__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
4operator.__concat__(1,2)
Traceback (most recent call last):
File"", line 1, in
TypeError:'int' object can't be concatenated
当对两个字符串执行时,它执行字符串串联。
1
2operator.__concat__('a','b')
'ab'
实际行为是否有差别/限制?生产预期结果(EDOCX1&4)和文献都说这两者都"归还A+B"。
注:OP was talking about the operatormodules,not special methods.还注意到没有特别的__concat__方法。
更新年份。