10.3. operator — 作为函数的标准运算符 — Python 文档

来自菜鸟教程
Python/docs/3.6/library/operator
跳转至:导航、​搜索

10.3. 操作员 — 标准运算符作为函数

源代码: :source:`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)

ab 之间进行“丰富的比较”。 具体来说,lt(a, b)相当于a < ble(a, b)相当于a <= beq(a, b)相当于a == bne(a, b)相当于a != bgt(a, b)相当于a > bge(a, b)相当于a >= b。 请注意,这些函数可以返回任何值,这些值可能会也可能不会被解释为布尔值。 有关丰富比较的更多信息,请参阅 Comparisons

逻辑运算也普遍适用于所有对象,并支持真值测试、身份测试和布尔运算:

operator.not_(obj)

operator.__not__(obj)

返回 not obj 的结果。 (注意,对象实例没有 __not__() 方法;只有解释器核心定义了这个操作。 结果受 __bool__()__len__() 方法的影响。)
operator.truth(obj)
如果 obj 为真,则返回 True,否则返回 False。 这等效于使用 bool 构造函数。
operator.is_(a, b)
返回 a is b。 测试对象身份。
operator.is_not(a, b)
返回 a is not b。 测试对象身份。

数学和按位运算是最多的:

operator.abs(obj)

operator.__abs__(obj)

返回 obj 的绝对值。
operator.add(a, b)

operator.__add__(a, b)

对于 ab 数字,返回 a + b
operator.and_(a, b)

operator.__and__(a, b)

返回 ab 的按位和。
operator.floordiv(a, b)

operator.__floordiv__(a, b)

返回 a // b
operator.index(a)

operator.__index__(a)

返回转换为整数的 a。 相当于 a.__index__()
operator.inv(obj)

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

返回数字 obj 的按位倒数。 这相当于 ~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)

对于 ab 数字,返回 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)

返回 ab 的按位或。
operator.pos(obj)

operator.__pos__(obj)

返回 obj 正数 (+obj)。
operator.pow(a, b)

operator.__pow__(a, b)

对于 ab 数字,返回 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 是 0.66 而不是 0。 这也称为“真”除法。
operator.xor(a, b)

operator.__xor__(a, b)

返回 ab 的按位异或。

使用序列的操作(其中一些也使用映射)包括:

operator.concat(a, b)

operator.__concat__(a, b)

ab 序列返回 a + b
operator.contains(a, b)

operator.__contains__(a, b)

返回测试结果 b in a。 注意反向操作数。
operator.countOf(a, b)
返回 ab 的出现次数。
operator.delitem(a, b)

operator.__delitem__(a, b)

删除索引 ba 的值。
operator.getitem(a, b)

operator.__getitem__(a, b)

返回索引 ba 的值。
operator.indexOf(a, b)
返回 ab 第一次出现的索引。
operator.setitem(a, b, c)

operator.__setitem__(a, b, c)

将索引 b 处的 a 的值设置为 c
operator.length_hint(obj, default=0)

返回对象 o 的估计长度。 首先尝试返回其实际长度,然后使用 object.__length_hint__() 进行估计,最后返回默认值。

3.4 版中的新功能。

operator 模块还定义了用于通用属性和项目查找的工具。 这些对于将快速字段提取器作为 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__() 方法接受的任何类型。 字典接受任何可散列的值。 列表、元组和字符串接受索引或切片:

>>> itemgetter(1)('ABCDEFG')
'B'
>>> itemgetter(1,3,5)('ABCDEFG')
('B', 'D', 'F')
>>> itemgetter(slice(2,None))('ABCDEFG')
'CDEFG'

使用 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...])

返回一个可调用对象,该对象在其操作数上调用方法 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

10.3.1. 将运算符映射到函数

此表显示抽象操作如何对应于 Python 语法中的运算符符号以及 operator 模块中的函数。

手术 句法 功能
添加 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)
按位或 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)


10.3.2. 就地运算符

许多操作都有一个“就地”版本。 下面列出的函数比通常的语法提供了对就地运算符更原始的访问; 例如,语句 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'

对于列表和字典等可变目标, inplace 方法将执行更新,因此不需要后续分配:

>>> 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) 相当于 ab 序列的 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