operator – 标准运算符作为函数详解(3)Python语言的功能编程模块(必读进阶学习教程)(参考资料)
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.objnot_()operator.__not__(obj)- 返回 not obj 的结果。 (请注意,对象实例没有 __not__() 方法;只有解释器核心定义此操作。结果受 __bool__() 和 __len__() 方法的影响。)
operator.objtruth()- 如果 obj 为真,则返回 True,否则返回 False。 这相当于使用 bool 构造函数。
operator.ais_(b,)- 返回a是b。 测试对象标识。
operator.ais_not(b,)- 返回 a 不是 b。 测试对象标识。
数学和按位运算是最多的:
operator.objabs()operator.obj__abs__()- 返回obj的绝对值。
operator.aadd(b,)operator.a__add__(b,)- 对于 a 和 b 数字,返回 a + b。
operator.and_(a, b)operator.a__and__(b,)- 返回 a 和 b 的按位与。
operator.afloordiv(b,)operator.a__floordiv__(b,)- 返回
a // b
operator.aindex()operator.a__index__()- 返回一个转换为整数。 等同于 a.__index__()。
operator.objinv()operator.objinvert()operator.obj__inv__()operator.obj__invert__()- 返回数字 obj 的按位反转。 这相当于 ~obj。
operator.alshift(b,)operator.a__lshift__(b,)- 返回左移 b 的 a。
operator.amod(b,)operator.a__mod__(b,)- 返回
a % b
operator.amul(b,)operator.a__mul__(b,)- 对于 a 和 b 数字,返回 a * b。
operator.amatmul(b,)operator.a__matmul__(b,)- 返回
a @ b版本3.5中的新功能。
operator.objneg()operator.obj__neg__()- 返回 obj 取反 (-obj)。
operator.aor_(b,)operator.a__or__(b,)- 返回 a 和 b 的按位或。
operator.objpos()operator.obj__pos__()- 返回 obj 正数 (+obj)。
operator.apow(b,)operator.a__pow__(b,)- 返回 a ** b,对于 a 和 b 数字。
operator.arshift(b,)operator.a__rshift__(b,)- 返回右移 b 的 a。
operator.asub(b,)operator.a__sub__(b,)- 返回
a - b
operator.atruediv(b,)operator.a__truediv__(b,)- 返回 a / b,其中 2/3 是 .66 而不是 0。这也称为“真”除法。
operator.axor(b,)operator.a__xor__(b,)- 返回 a 和 b 的按位异或。
适用于序列的操作(其中一些也适用于映射)包括:
operator.aconcat(b,)operator.a__concat__(b,)- 为 a 和 b 序列返回 a + b。
operator.acontains(b,)operator.a__contains__(b,)- 在 a 中返回测试 b 的结果。 注意反转的操作数。
operator.acountOf(b,)- 返回 b 在 a 中出现的次数。
operator.adelitem(b,)operator.a__delitem__(b,)- 删除索引 b 处 a 的值。
operator.agetitem(b,)operator.a__getitem__(b,)- 返回索引 b 处 a 的值。
operator.aindexOf(b,)- 返回 b 在 a 中第一次出现的索引。
operator.asetitem(b,c,)operator.a__setitem__(b,c,)- 将索引 b 处的 a 的值设置为 c。
operator.objlength_hint(default=0,)- 返回对象 o 的估计长度。 首先尝试返回其实际长度,然后使用 object.__length_hint__() 进行估算,最后返回默认值。
3.4 版中的新功能。
operator 模块还定义了用于通用属性和项目查找的工具。 这些对于制作快速字段提取器作为 map()、sorted()、itertools.groupby() 或其他需要函数参数的函数的参数很有用。
operator.attrattrgetter()operator.*attrsattrgetter()- 返回一个可调用对象,该对象从其操作数中获取 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.itemitemgetter()operator.*itemsitemgetter()- 返回一个可调用对象,该对象使用操作数的 __getitem__() 方法从其操作数中获取项目。 如果指定了多个项目,则返回查找值的元组。 例如:
- 在 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__() 方法接受的任何类型。 字典接受任何可散列的值。 列表、元组和字符串接受索引或切片:
>>> 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.namemethodcaller(args…[,])- 返回一个调用其操作数上的方法名称的可调用对象。 如果给出了额外的参数和/或关键字参数,它们也将被提供给该方法。 例如:
- 在 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 语法中的运算符符号和运算符模块中的函数。
| 手术 | 句法 | 功能 |
|---|---|---|
| 加成 | 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) |
| 按位和 | a & b |
and_(a, b) |
| 按位排他或 | a ^ b |
xor(a, b) |
| 按位反转 | ~ a |
invert(a) |
| 按位或 | a | b |
or_(a, b) |
| 幂 | a ** b |
pow(a, b) |
| 身分 | a is b |
is_(a, b) |
| 身分 | a is not b |
is_not(a, b) |
| 索引分配 | obj[k] = v |
setitem(obj, k, v) |
| 索引删除 | del obj[k] |
delitem(obj, k) |
| 索引 | obj[k] |
getitem(obj, k) |
| 左移 | a << b |
lshift(a, b) |
| 模 | 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) |
就地操作员
许多操作都有“就地”版本。 下面列出的函数提供了比通常语法更原始的就地操作符访问; 例如,语句 x += y 等同于 x = operator.iadd(x, y)。 另一种表达方式是说 z = operator.iadd(x, y) 等同于复合语句 z = x; z += y。
在这些示例中,请注意,当调用就地方法时,计算和赋值是在两个单独的步骤中执行的。 下面列出的就地函数只做第一步,调用就地方法。 第二步,赋值,没有处理。
对于字符串、数字和元组等不可变目标,计算更新后的值,但不会将其分配回输入变量:
>>> a = 'hello'
>>> iadd(a, ' world')
'hello world'
>>> a
'hello'
对于列表和字典等可变目标,就地方法将执行更新,因此不需要后续赋值:
>>> 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.aiand(b,)operator.a__iand__(b,)a = and(a, b) 等价于 a &= b。
operator.aiconcat(b,)operator.a__iconcat__(b,)- a = iconcat(a, b) 等同于 a += b 对于 a 和 b 序列。
operator.aifloordiv(b,)operator.a__ifloordiv__(b,)- a = ifloordiv(a, b) 等价于 a //= b。
operator.ailshift(b,)operator.a__ilshift__(b,)- a = ilshift(a, b) 等价于 a <<= b。
operator.aimod(b,)operator.a__imod__(b,)a = imod(a, b) 等价于 a %= b。
operator.aimul(b,)operator.a__imul__(b,)- a = imul(a, b) 等价于 a *= b。
operator.aimatmul(b,)operator.a__imatmul__(b,)a = imatmul(a, b) 等价于 a @= b。版本3.5中的新功能。
operator.aior(b,)operator.a__ior__(b,)- a = ior(a, b) 等价于 a |= b。
operator.aipow(b,)operator.a__ipow__(b,)- a = ipow(a, b) 等价于 a **= b。
operator.airshift(b,)operator.a__irshift__(b,)- a = irshift(a, b) 等价于 a >>= b。
operator.aisub(b,)operator.a__isub__(b,)- a = isub(a, b) 等价于 a -= b。
operator.aitruediv(b,)operator.a__itruediv__(b,)- a = itruediv(a, b) 等价于 a /= b。
operator.aixor(b,)operator.a__ixor__(b,)a = ixor(a, b) 等价于 a ^= b。