numpy.lib.mixins.NDArrayOperatorsMixin#

class numpy.lib.mixins.NDArrayOperatorsMixin[source]#

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

此類實現了幾乎所有 Python 內建運算子的特殊方法,這些運算子在 operator 模組中定義,包括比較(==> 等)和算術(+*- 等),透過委託給 __array_ufunc__ 方法實現,子類必須實現該方法。

它對於編寫不繼承自 numpy.ndarray 的類非常有用,但這些類應當像陣列一樣支援算術運算和 NumPy 通用函式,詳見 NEP 13 — 用於覆蓋 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 的互動保持明確定義的型別轉換層次。