numpy.lib.mixins.NDArrayOperatorsMixin#

class numpy.lib.mixins.NDArrayOperatorsMixin[原始碼]#

混入類別,使用 __array_ufunc__ 定義所有運算子特殊方法。

此類別實作 Python operator 模組中定義的幾乎所有內建運算子的特殊方法,包括比較 (==> 等) 和算術 (+*- 等),方法是延遲到 __array_ufunc__ 方法,子類別必須實作此方法。

它適用於編寫不繼承自 numpy.ndarray 的類別,但應支援算術和 NumPy 通用函式,如 覆寫 Ufunc 的機制中所述。

作為一個簡單的範例,請考慮 ArrayLike 類別的此實作,它僅封裝 NumPy 陣列並確保任何算術運算的結果也是 ArrayLike 物件

>>> import numbers
>>> class ArrayLike(np.lib.mixins.NDArrayOperatorsMixin):
...     def __init__(self, value):
...         self.value = np.asarray(value)
...
...     # One might also consider adding the built-in list type to this
...     # list, to support operations like np.add(array_like, list)
...     _HANDLED_TYPES = (np.ndarray, numbers.Number)
...
...     def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
...         out = kwargs.get('out', ())
...         for x in inputs + out:
...             # Only support operations with instances of
...             # _HANDLED_TYPES. Use ArrayLike instead of type(self)
...             # for isinstance to allow subclasses that don't
...             # override __array_ufunc__ to handle ArrayLike objects.
...             if not isinstance(
...                 x, self._HANDLED_TYPES + (ArrayLike,)
...             ):
...                 return NotImplemented
...
...         # Defer to the implementation of the ufunc
...         # on unwrapped values.
...         inputs = tuple(x.value if isinstance(x, ArrayLike) else x
...                     for x in inputs)
...         if out:
...             kwargs['out'] = tuple(
...                 x.value if isinstance(x, ArrayLike) else x
...                 for x in out)
...         result = getattr(ufunc, method)(*inputs, **kwargs)
...
...         if type(result) is tuple:
...             # multiple return values
...             return tuple(type(self)(x) for x in result)
...         elif method == 'at':
...             # no return value
...             return None
...         else:
...             # one return value
...             return type(self)(result)
...
...     def __repr__(self):
...         return '%s(%r)' % (type(self).__name__, self.value)

ArrayLike 物件與數字或 numpy 陣列之間的互動中,結果始終是另一個 ArrayLike

>>> x = ArrayLike([1, 2, 3])
>>> x - 1
ArrayLike(array([0, 1, 2]))
>>> 1 - x
ArrayLike(array([ 0, -1, -2]))
>>> np.arange(3) - x
ArrayLike(array([-1, -1, -1]))
>>> x - np.arange(3)
ArrayLike(array([1, 1, 1]))

請注意,與 numpy.ndarray 不同,ArrayLike 不允許與任意、無法辨識的類型進行運算。這確保與 ArrayLike 的互動保留了明確定義的轉換階層。