# `operator` --- 標準運算子替代函式

原始碼：Lib/operator.py

The `operator` module exports a set of efficient functions corresponding to the intrinsic operators of Python. For example, `operator.add(x, y)` is equivalent to the expression `x+y`. Many function names are those used for special methods, without the double underscores. For backward compatibility, many of these have a variant with the double underscores kept. The variants without the double underscores are preferred for clarity.

函式種類有物件的比較運算、邏輯運算、數學運算以及序列運算。

物件比較函式適用於所有物件，函式根據它們對應的 rich comparison 運算子命名：

operator.lt(a, b)
operator.le(a, b)
operator.eq(a, b)
operator.ne(a, b)
operator.ge(a, b)
operator.gt(a, b)
operator.__lt__(a, b)
operator.__le__(a, b)
operator.__eq__(a, b)
operator.__ne__(a, b)
operator.__ge__(a, b)
operator.__gt__(a, b)

  在 a 和 b 之間進行 "rich comparison"。具體來說，`lt(a, b)` 與 `a < b` 相同，`le(a, b)` 與 `a <= b` 相同，`eq(a, b)` 與 `a == b` 相同，`ne(a, b)` 與 `a != b` 相同，`gt(a, b)` 與 `a > b` 相同，`ge(a, b)` 與 `a >= b` 相同。注意這些函式可以回傳任何值，無論它是否可當作 boolean（布林）值。關於 rich comparison 的更多資訊請參考 Comparisons。

邏輯運算通常也適用於所有物件，並且支援真值檢測、識別性測試和 boolean 運算：

operator.not_(obj)
operator.__not__(obj)

  回傳 `not` obj 的結果。（請注意物件實例並沒有 `__not__()` method（方法）；只有直譯器核心定義此操作。結果會受 `__bool__()` 和 `__len__()` method 影響。）

operator.truth(obj)

  如果 obj 為真值則回傳 `True`，否則回傳 `False`。這等價於使用 `bool` 建構函式。

operator.is_(a, b)

  回傳 `a is b`。測試物件識別性。

operator.is_not(a, b)

  回傳 `a is not b`。測試物件識別性。

operator.is_none(a)

  回傳 `a is None`。測試物件識別性。

  在 3.14 版被加入.

operator.is_not_none(a)

  回傳 `a is not None`。測試物件識別性。

  在 3.14 版被加入.

數學和位元運算的種類是最多的：

operator.abs(obj)
operator.__abs__(obj)

  回傳 obj 的絕對值。

operator.add(a, b)
operator.__add__(a, b)

  對於數字 a 和 b，回傳 `a + b`。

operator.and_(a, b)
operator.__and__(a, b)

  回傳 x 和 y 位元運算與 (and) 的結果。

operator.floordiv(a, b)
operator.__floordiv__(a, b)

  回傳 `a // b`。

operator.index(a)
operator.__index__(a)

  回傳 a 轉換為整數的結果。等價於 `a.__index__()`。

  在 3.10 版的變更: 結果總是 `int` 型別。在過去的版本中，結果可能為 `int` 子類別的實例。

operator.inv(obj)
operator.invert(obj)
operator.__inv__(obj)
operator.__invert__(obj)

  回傳數字 obj 按位元取反 (inverse) 的結果。這等價於 `~obj`。

operator.lshift(a, b)
operator.__lshift__(a, b)

  回傳 a 左移 b 位的結果。

operator.mod(a, b)
operator.__mod__(a, b)

  回傳 `a % b`。

operator.mul(a, b)
operator.__mul__(a, b)

  對於數字 a 和 b，回傳 `a * b`。

operator.matmul(a, b)
operator.__matmul__(a, b)

  回傳 `a @ b`。

  在 3.5 版被加入.

operator.neg(obj)
operator.__neg__(obj)

  回傳 obj 取負值的結果 (`-obj`)。

operator.or_(a, b)
operator.__or__(a, b)

  回傳 a 和 b 按位元或 (or) 的結果。

operator.pos(obj)
operator.__pos__(obj)

  回傳 obj 取正的結果 (`+obj`)。

operator.pow(a, b)
operator.__pow__(a, b)

  對於數字 a 和 b，回傳 `a ** b`。

operator.rshift(a, b)
operator.__rshift__(a, b)

  回傳 a 右移 b 位的結果。

operator.sub(a, b)
operator.__sub__(a, b)

  回傳 `a - b`。

operator.truediv(a, b)
operator.__truediv__(a, b)

  回傳 `a / b`，例如 2/3 將等於 .66 而不是 0。這也被稱為「真」除法。

operator.xor(a, b)
operator.__xor__(a, b)

  回傳 a 和 b 按位元異或 (exclusive or) 的結果。

適用於序列的操作（其中一些也適用於對映 (mapping)），包括：

operator.concat(a, b)
operator.__concat__(a, b)

  對於序列 a 和 b，回傳 `a + b`。

operator.contains(a, b)
operator.__contains__(a, b)

  回傳 `b in a` 檢測的結果。請注意運算元是反序的。

operator.countOf(a, b)

  回傳 b 在 a 中的出現次數。

operator.delitem(a, b)
operator.__delitem__(a, b)

  移除 a 中索引為 b 的值。

operator.getitem(a, b)
operator.__getitem__(a, b)

  回傳 a 中索引為 b 的值。

operator.indexOf(a, b)

  回傳 b 在 a 中首次出現所在的索引。

operator.setitem(a, b, c)
operator.__setitem__(a, b, c)

  將 a 中索引為 b 的值設為 c。

operator.length_hint(obj, default=0)

  回傳物件 obj 的估計長度。首先嘗試回傳其實際長度，再使用 `object.__length_hint__()` 得出估計值，最後才是回傳預設值。

  在 3.4 版被加入.

以下操作適用於可呼叫物件：

operator.call(obj, /, *args, **kwargs)
operator.__call__(obj, /, *args, **kwargs)

  回傳 `obj(*args, **kwargs)`。

  在 3.11 版被加入.

The `operator` module also defines tools for generalized attribute and item lookups. These are useful for making fast field extractors as arguments for `map()`, `sorted()`, `itertools.groupby()`, or other functions that expect a function argument.

operator.attrgetter(attr)
operator.attrgetter(*attrs)

  回傳一個可從運算元中取得 attr 的可呼叫 (callable) 物件。如果請求了一個以上的屬性，則回傳一個包含屬性的 tupple（元組）。屬性名稱還可包含點號。例如：

  - 在 `f = attrgetter('name')` 之後，呼叫 `f(b)` 將回傳 `b.name`。

  - 在 `f = attrgetter('name', 'date')` 之後，呼叫 `f(b)` 將回傳 `(b.name, b.date)`。

  - 在 `f = attrgetter('name.first', 'name.last')` 之後，呼叫 `f(b)` 將回傳 `(b.name.first, b.name.last)`。

  等價於：

      def attrgetter(*items):
          if any(not isinstance(item, str) for item in items):
              raise TypeError('屬性名稱必須是一個字串')
          if len(items) == 1:
              attr = items[0]
              def g(obj):
                  return resolve_attr(obj, attr)
          else:
              def g(obj):
                  return tuple(resolve_attr(obj, attr) for attr in items)
          return g

      def resolve_attr(obj, attr):
          for name in attr.split("."):
              obj = getattr(obj, name)
          return obj

operator.itemgetter(item)
operator.itemgetter(*items)

  回傳一個使用運算元的 `__getitem__()` 方法從運算元中取得 item 的可呼叫物件。如果指定了多個條目，則回傳一個查詢值的 tupple。例如：

  - 在 `f = itemgetter(2)` 之後，呼叫 `f(r)` 將回傳 `r[2]`。

  - 在 `g = itemgetter(2, 5, 3)` 之後，呼叫 `g(r)` 將回傳 `(r[2], r[5], r[3])`。

  等價於：

      def itemgetter(*items):
          if len(items) == 1:
              item = items[0]
              def g(obj):
                  return obj[item]
          else:
              def g(obj):
                  return tuple(obj[item] for item in items)
          return g

  傳入的條目可以為運算元的 `__getitem__()` 所接受的任何型別。dictionary（字典）接受任意可雜湊的值。list、tupple 和字串接受索引或切片：

      >>> itemgetter(1)('ABCDEFG')
      'B'
      >>> itemgetter(1, 3, 5)('ABCDEFG')
      ('B', 'D', 'F')
      >>> itemgetter(slice(2, None))('ABCDEFG')
      'CDEFG'
      >>> soldier = dict(rank='captain', name='dotterbart')
      >>> itemgetter('rank')(soldier)
      'captain'

  使用 `itemgetter()` 從 tuple 中提取特定欄位的例子：

      >>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
      >>> getcount = itemgetter(1)
      >>> list(map(getcount, inventory))
      [3, 2, 5, 1]
      >>> sorted(inventory, key=getcount)
      [('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]

operator.methodcaller(name, /, *args, **kwargs)

  回傳一個在運算元上呼叫 name method 的可呼叫物件。如果給定額外的引數和/或關鍵字引數，它們也將被傳給該 method。例如：

  - 在 `f = methodcaller('name')` 之後，呼叫 `f(b)` 將回傳 `b.name()`。

  - 在 `f = methodcaller('name', 'foo', bar=1)` 之後，呼叫 `f(b)` 將回傳 `b.name('foo', bar=1)`。

  等價於：

      def methodcaller(name, /, *args, **kwargs):
          def caller(obj):
              return getattr(obj, name)(*args, **kwargs)
          return caller

## 運算子與函式間的對映

This table shows how abstract operations correspond to operator symbols in the Python syntax and the functions in the `operator` module.

運算 | 語法 | 函式
--- | --- | ---
加法 | `a + b` | `add(a, b)`
字串串接 | `seq1 + seq2` | `concat(seq1, seq2)`
包含性檢測 | `obj in seq` | `contains(seq, obj)`
除法 | `a / b` | `truediv(a, b)`
除法 | `a // b` | `floordiv(a, b)`
按位元與 (And) | `a & b` | `and_(a, b)`
按位元互斥或 (Exclusive Or) | `a ^ b` | `xor(a, b)`
按位元取反 (Inversion) | `~ a` | `invert(a)`
按位元或 (Or) | `a | b` | `or_(a, b)`
取冪 | `a ** b` | `pow(a, b)`
識別性 | `a is b` | `is_(a, b)`
識別性 | `a is not b` | `is_not(a, b)`
識別性 | `a is None` | `is_none(a)`
識別性 | `a is not None` | `is_not_none(a)`
索引賦值 | `obj[k] = v` | `setitem(obj, k, v)`
索引刪除 | `del obj[k]` | `delitem(obj, k)`
索引取值 | `obj[k]` | `getitem(obj, k)`
左移 | `a << b` | `lshift(a, b)`
模除 (Modulo) | `a % b` | `mod(a, b)`
乘法 | `a * b` | `mul(a, b)`
矩陣乘法 | `a @ b` | `matmul(a, b)`
反相（算術） | `- a` | `neg(a)`
反相（邏輯） | `not a` | `not_(a)`
正數 | `+ a` | `pos(a)`
右移 | `a >> b` | `rshift(a, b)`
切片賦值 | `seq[i:j] = values` | `setitem(seq, slice(i, j), values)`
切片刪除 | `del seq[i:j]` | `delitem(seq, slice(i, j))`
切片取值 | `seq[i:j]` | `getitem(seq, slice(i, j))`
字串格式化 | `s % obj` | `mod(s, obj)`
減法 | `a - b` | `sub(a, b)`
真值檢測 | `obj` | `truth(obj)`
比較大小 | `a < b` | `lt(a, b)`
比較大小 | `a <= b` | `le(a, b)`
相等性 | `a == b` | `eq(a, b)`
不等性 | `a != b` | `ne(a, b)`
比較大小 | `a >= b` | `ge(a, b)`
比較大小 | `a > b` | `gt(a, b)`

## 原地 (in-place) 運算子

許多運算都有「原地」版本。以下列出的是提供對原地運算子（與一般語法相比）更底層存取的函式，例如 statement `x += y` 相當於 `x = operator.iadd(x, y)`。換一種方式來講就是 `z = operator.iadd(x, y)` 等價於複合陳述式 `z = x; z += y`。

在這些例子中，請注意當呼叫一個原地方法時，運算和賦值是分成兩個步驟來執行的。下面列出的原地函式只執行第一步，即呼叫原地方法，第二步賦值則不加處理。

對於不可變 (immutable) 的目標例如字串、數字和 tupple，更新的值會被計算，但不會被再被賦值給輸入變數：

    >>> a = 'hello'
    >>> iadd(a, ' world')
    'hello world'
    >>> a
    'hello'

對於可變 (mutable) 的目標例如 list 和 dictionary，原地方法將執行更新，因此不需要後續賦值操作：

    >>> s = ['h', 'e', 'l', 'l', 'o']
    >>> iadd(s, [' ', 'w', 'o', 'r', 'l', 'd'])
    ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
    >>> s
    ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']

operator.iadd(a, b)
operator.__iadd__(a, b)

  `a = iadd(a, b)` 等價於 `a += b`。

operator.iand(a, b)
operator.__iand__(a, b)

  `a = iand(a, b)` 等價於 `a &= b`。

operator.iconcat(a, b)
operator.__iconcat__(a, b)

  `a = iconcat(a, b)` 等價於 `a += b`，其中 a 和 b 為序列。

operator.ifloordiv(a, b)
operator.__ifloordiv__(a, b)

  `a = ifloordiv(a, b)` 等價於 `a //= b`。

operator.ilshift(a, b)
operator.__ilshift__(a, b)

  `a = ilshift(a, b)` 等價於 `a <<= b`。

operator.imod(a, b)
operator.__imod__(a, b)

  `a = imod(a, b)` 等價於 `a %= b`。

operator.imul(a, b)
operator.__imul__(a, b)

  `a = imul(a, b)` 等價於 `a *= b`。

operator.imatmul(a, b)
operator.__imatmul__(a, b)

  `a = imatmul(a, b)` 等價於 `a @= b`。

  在 3.5 版被加入.

operator.ior(a, b)
operator.__ior__(a, b)

  `a = ior(a, b)` 等價於 `a |= b`。

operator.ipow(a, b)
operator.__ipow__(a, b)

  `a = ipow(a, b)` 等價於 `a **= b`。

operator.irshift(a, b)
operator.__irshift__(a, b)

  `a = irshift(a, b)` 等價於 `a >>= b`。

operator.isub(a, b)
operator.__isub__(a, b)

  `a = isub(a, b)` 等價於 `a -= b`。

operator.itruediv(a, b)
operator.__itruediv__(a, b)

  `a = itruediv(a, b)` 等價於 `a /= b`。

operator.ixor(a, b)
operator.__ixor__(a, b)

  `a = ixor(a, b)` 等價於 `a ^= b`。