为什么像abs这样的内置函数适用于numpy数组?

时间:2014-01-06 15:20:50

标签: python arrays numpy

我感到惊讶的是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__它也适用于列表,但它没有。

3 个答案:

答案 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

但是,这不适用于内置类型,例如listdict

答案 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__(但理解通常更可取)