operator
--- 標準運算符替代函數?
源代碼: Lib/operator.py
operator
模塊提供了一套與Python的內置運算符對應的高效率函數。例如,operator.add(x, y)
與表達式 x+y
相同。 許多函數名與特殊方法名相同,只是沒有雙下劃線。為了向后兼容性,也保留了許多包含雙下劃線的函數。為了表述清楚,建議使用沒有雙下劃線的函數。
函數包含的種類有:對象的比較運算、邏輯運算、數學運算以及序列運算。
對象比較函數適用于所有的對象,函數名根據它們對應的比較運算符命名。
- 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 之間進行全比較。具體的,
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
相同。注意這些函數可以返回任何值,無論它是否可當作布爾值。關于全比較的更多信息請參考 比較運算 。
邏輯運算通常也適用于所有對象,并且支持真值檢測、標識檢測和布爾運算:
- operator.not_(obj)?
- operator.__not__(obj)?
返回
not
obj 的結果。 (請注意對象實例并沒有__not__()
方法;只有解釋器核心可定義此操作。 結果會受__bool__()
和__len__()
方法影響。)
- operator.is_(a, b)?
返回
a is b
。 檢測對象標識。
- operator.is_not(a, b)?
返回
a is not 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 按位取反的結果。 這等價于
~obj
。
適用于序列的操作(其中一些也適用于映射)包括:
- operator.countOf(a, b)?
返回 b 在 a 中的出現(xiàn)次數。
- operator.indexOf(a, b)?
返回 b 在 a 中首次出現(xiàn)所在的索引號。
- operator.length_hint(obj, default=0)?
返回對象 o 的估計長度。 首先嘗試返回其實際長度,再使用
object.__length_hint__()
得出估計值,最后返回默認值。3.4 新版功能.
The following operation works with callables:
- operator.call(obj, /, *args, **kwargs)?
- operator.__call__(obj, /, *args, **kwargs)?
Return
obj(*args, **kwargs)
.3.11 新版功能.
operator
模塊還定義了一些用于常規(guī)屬性和條目查找的工具。 這些工具適合用來編寫快速字段提取器作為 map()
, sorted()
, itertools.groupby()
或其他需要相應函數參數的函數的參數。
- operator.attrgetter(attr)?
- operator.attrgetter(*attrs)
返回一個可從操作數中獲取 attr 的可調用對象。 如果請求了一個以上的屬性,則返回一個屬性元組。 屬性名稱還可包含點號。 例如:
在
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('attribute name must be a string') 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 的可調用對象。 如果指定了多個條目,則返回一個查找值的元組。 例如:在
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__()
所接受的任何類型。 字典接受任意可哈希的值。 列表、元組和字符串接受 index 或 slice 對象:>>> 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()
從元組的記錄中提取特定字段的例子:>>> 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 方法的可調用對象。 如果給出額外的參數和/或關鍵字參數,它們也將被傳給該方法。 例如:
在
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
將運算符映射到函數?
以下表格顯示了抽象運算是如何對應于 Python 語法中的運算符和 operator
模塊中的函數的。
運算 |
語法 |
函數 |
---|---|---|
加法 |
|
|
字符串拼接 |
|
|
包含測試 |
|
|
除法 |
|
|
除法 |
|
|
按位與 |
|
|
按位異或 |
|
|
按位取反 |
|
|
按位或 |
|
|
取冪 |
|
|
標識 |
|
|
標識 |
|
|
索引賦值 |
|
|
索引刪除 |
|
|
索引取值 |
|
|
左移 |
|
|
取模 |
|
|
乘法 |
|
|
矩陣乘法 |
|
|
取反(算術) |
|
|
取反(邏輯) |
|
|
正數 |
|
|
右移 |
|
|
切片賦值 |
|
|
切片刪除 |
|
|
切片取值 |
|
|
字符串格式化 |
|
|
減法 |
|
|
真值測試 |
|
|
比較 |
|
|
比較 |
|
|
相等 |
|
|
不等 |
|
|
比較 |
|
|
比較 |
|
|
原地運算符?
許多運算都有“原地”版本。 以下列出的是提供對原地運算符相比通常語法更底層訪問的函數,例如 statement x += y
相當于 x = operator.iadd(x, y)
。 換一種方式來講就是 z = operator.iadd(x, y)
等價于語句塊 z = x; z += y
。
在這些例子中,請注意當調用一個原地方法時,運算和賦值是分成兩個步驟來執(zhí)行的。 下面列出的原地函數只執(zhí)行第一步即調用原地方法。 第二步賦值則不加處理。
對于不可變的目標例如字符串、數字和元組,更新的值會被計算,但不會被再被賦值給輸入變量:
>>> a = 'hello'
>>> iadd(a, ' world')
'hello world'
>>> a
'hello'
對于可變的目標例如列表和字典,原地方法將執(zhí)行更新,因此不需要后續(xù)賦值操作:
>>> 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']