我感到惊讶的是abs
适用于numpy数组,但不适用于列表。那是为什么?
import numpy as np
abs(np.array((1,-2)))
array([1, 2])
abs([1,-1])
TypeError: bad operand type for abs(): 'list'
此外,像sum
这样的内置函数也适用于numpy数组。我想这是因为numpy数组支持__getitem__
?但是在abs
的情况下,如果它依赖于__getitem__
它也适用于列表,但它没有。
答案 0 :(得分:21)
那是因为numpy.ndarray
实现了__abs__(self)
方法。只需为自己的班级提供,abs()
将神奇地工作。对于非内置类型,您也可以在事后提供此功能。 E.g。
class A:
"A class without __abs__ defined"
def __init__(self, v):
self.v = v
def A_abs(a):
"An 'extension' method that will be added to `A`"
return abs(a.v)
# Make abs() work with an instance of A
A.__abs__ = A_abs
但是,这不适用于内置类型,例如list
或dict
。
答案 1 :(得分:4)
abs
函数查找__abs__
方法。
你也可以像numpy一样在你的课程中实现__abs__
方法,这样abs就适用于它们。
即
class A(object):
def __abs__(self):
return 8
>>> a= A()
>>> abs(a)
8
>>>
答案 2 :(得分:2)
sum
适用于iterables,例如list或numpy数组。
abs
适用于定义__abs__
方法的值,例如数字或numpy.arrays:
>>> x = -1
>>> x.__abs__()
1
>>> class A(object):
... def __abs__(self):
... return 12
>>> a = A()
>>> abs(a)
12
list
不定义此方法,但您可以使用地图或列表推导(分别为map(abs, [1, -1])
和[abs(x) for x in [1,-1]]
)来满足您的需求。如果你喜欢矫枉过正,你也可以将列表子类化并定义类似numpy的__abs__
(但理解通常更可取)