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
模块 并没有太多用处。该模块主要在您需要传递执行操作的函数时使用,例如传递给函数式函数如map
、filter
或 reduce
等。但通常情况下,您可以直接使用 +
运算符。
至于下划线函数(__add__
和 __concat__
),它们只是 别名:
__add__ = add
__concat__ = concat
__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
模块对于将操作符传递给 reduce()
函数非常有用。 - fferrireduce()
,因为函数式编程太酷了 :) - fferrioperator.__add__(a, b)
: 返回 a + b
,其中a
和 b
是数字 *。operator.__concat__(a, b)
: 返回 a + b
,其中a
和 b
是序列。它们之间有什么区别呢?
例如,您无法连接整数:
>>> 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): 它将尝试执行
operator.__add__(a, b)
返回 a + b,其中 a 和 b 是数字。
operator.__concat__(a, b)
返回 a + b,其中 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'
operator.add("a","b")
产生了预期的结果("a"+"b"=>"ab"
),文档说两者都“返回a + b”。 - user2864740
__concat__
不像__add__
一样是一个“魔法方法”:https://docs.python.org/2/reference/datamodel.html - jonrsharpe__concat__
实际上没有定义在任何对象上 - 这就是为什么你说它不是一个魔术方法。如果您发布一个回答,概述了我的困惑主要源于operator
模块使用与魔术方法名称相同的方法名称,那么我会接受这种解释。 - ArtOfWarfare