4.4. operator — 内置操作符接口 | 算法 |《python 3 标准库实例教程》| python 技术论坛-金年会app官方网

未匹配的标注

目的:内置运算符的函数式接口。

使用迭代器进行编程有时需要为简单表达式创建小函数。有时,这些可以实现为 lambda 函数,但对于某些操作,根本不需要新函数。operator 模块定义了与算术,比较和与标准对象api相对应的其他操作的内置操作相对应的函数。

逻辑运算

有一些函数可以确定一个值的布尔等价,对其取反来创建相反的布尔值,并比较对象以查看它们是否相同。

operator_boolean.py

from operator import *
a = -1
b = 5
print('a =', a)
print('b =', b)
print()
print('not_(a)     :', not_(a))
print('truth(a)    :', truth(a))
print('is_(a, b)   :', is_(a, b))
print('is_not(a, b):', is_not(a, b))

not_() 包含尾下划线,因为 not 是一个 python 关键字。truth() 是一样的逻辑,应用在 if 语句中测试一个表达式或将表达式转换为 boolis_() 实现 is 关键字使用的相同检查,is_not() 执行相同的测试并返回相反的答案。

$ python3 operator_boolean.py
a = -1
b = 5
not_(a)     : false
truth(a)    : true
is_(a, b)   : false
is_not(a, b): true

比较运算符

支持所有的富比较运算符。

operator_comparisons.py

from operator import *
a = 1
b = 5.0
print('a =', a)
print('b =', b)
for func in (lt, le, eq, ne, ge, gt):
    print('{}(a, b): {}'.format(func.__name__, func(a, b)))

这些函数等同于使用 <<===>=> 的表达式语法。

$ python3 operator_comparisons.py
a = 1
b = 5.0
lt(a, b): true
le(a, b): true
eq(a, b): false
ne(a, b): true
ge(a, b): false
gt(a, b): false

算术运算符

操纵数值的算术运算符同样也受到支持。

operator_math.py

from operator import *
a = -1
b = 5.0
c = 2
d = 6
print('a =', a)
print('b =', b)
print('c =', c)
print('d =', d)
print('\npositive/negative:')
print('abs(a):', abs(a))
print('neg(a):', neg(a))
print('neg(b):', neg(b))
print('pos(a):', pos(a))
print('pos(b):', pos(b))
print('\narithmetic:')
print('add(a, b)     :', add(a, b))
print('floordiv(a, b):', floordiv(a, b))
print('floordiv(d, c):', floordiv(d, c))
print('mod(a, b)     :', mod(a, b))
print('mul(a, b)     :', mul(a, b))
print('pow(c, d)     :', pow(c, d))
print('sub(b, a)     :', sub(b, a))
print('truediv(a, b) :', truediv(a, b))
print('truediv(d, c) :', truediv(d, c))
print('\nbitwise:')
print('and_(c, d)  :', and_(c, d))
print('invert(c)   :', invert(c))
print('lshift(c, d):', lshift(c, d))
print('or_(c, d)   :', or_(c, d))
print('rshift(d, c):', rshift(d, c))
print('xor(c, d)   :', xor(c, d))

有两个独立的除法运算符:floordiv() (在 3.0 之前的python中实现的整数除法)和 truediv() (浮点除法)。

$ python3 operator_math.py
a = -1
b = 5.0
c = 2
d = 6
正/负:
abs(a): 1
neg(a): 1
neg(b): -5.0
pos(a): -1
pos(b): 5.0
四则运算:
add(a, b)     : 4.0
floordiv(a, b): -1.0
floordiv(d, c): 3
mod(a, b)     : 4.0
mul(a, b)     : -5.0
pow(c, d)     : 64
sub(b, a)     : 6.0
truediv(a, b) : -0.2
truediv(d, c) : 3.0
位运算:
and_(c, d)  : 2
invert(c)   : -3
lshift(c, d): 128
or_(c, d)   : 6
rshift(d, c): 1
xor(c, d)   : 4

序列运算符

使用序列的运算符可以分为四组:构建序列,搜索项目,访问内容以及从序列中删除项目。

operator_sequences.py

from operator import *
a = [1, 2, 3]
b = ['a', 'b', 'c']
print('a =', a)
print('b =', b)
print('\nconstructive:')
print('  concat(a, b):', concat(a, b))
print('\nsearching:')
print('  contains(a, 1)  :', contains(a, 1))
print('  contains(b, "d"):', contains(b, "d"))
print('  countof(a, 1)   :', countof(a, 1))
print('  countof(b, "d") :', countof(b, "d"))
print('  indexof(a, 5)   :', indexof(a, 1))
print('\naccess items:')
print('  getitem(b, 1)                  :',
      getitem(b, 1))
print('  getitem(b, slice(1, 3))        :',
      getitem(b, slice(1, 3)))
print('  setitem(b, 1, "d")             :', end=' ')
setitem(b, 1, "d")
print(b)
print('  setitem(a, slice(1, 3), [4, 5]):', end=' ')
setitem(a, slice(1, 3), [4, 5])
print(a)
print('\ndestructive:')
print('  delitem(b, 1)          :', end=' ')
delitem(b, 1)
print(b)
print('  delitem(a, slice(1, 3)):', end=' ')
delitem(a, slice(1, 3))
print(a)

其中一些操作,例如 setitem()delitem(),修改了序列并且不返回值。

$ python3 operator_sequences.py
a = [1, 2, 3]
b = ['a', 'b', 'c']
constructive:
  concat(a, b): [1, 2, 3, 'a', 'b', 'c']
searching:
  contains(a, 1)  : true
  contains(b, "d"): false
  countof(a, 1)   : 1
  countof(b, "d") : 0
  indexof(a, 5)   : 0
access items:
  getitem(b, 1)                  : b
  getitem(b, slice(1, 3))        : ['b', 'c']
  setitem(b, 1, "d")             : ['a', 'd', 'c']
  setitem(a, slice(1, 3), [4, 5]): [1, 4, 5]
destructive:
  delitem(b, 1)          : ['a', 'c']
  delitem(a, slice(1, 3)): [1]

就地操作

除了标准运算符之外,许多类型的对象还通过特殊运算符(如 = )支持“就地”修改。同样具有就地修改的功能:

operator_inplace.py

from operator import *
a = -1
b = 5.0
c = [1, 2, 3]
d = ['a', 'b', 'c']
print('a =', a)
print('b =', b)
print('c =', c)
print('d =', d)
print()
a = iadd(a, b)
print('a = iadd(a, b) =>', a)
print()
c = iconcat(c, d)
print('c = iconcat(c, d) =>', c)

这些示例仅演示了一些功能。有关完整的详细信息,请参阅标准库文档。

$ python3 operator_inplace.py
a = -1
b = 5.0
c = [1, 2, 3]
d = ['a', 'b', 'c']
a = iadd(a, b) => 4.0
c = iconcat(c, d) => [1, 2, 3, 'a', 'b', 'c']

属性和项目 "getters"

operator 模块最不寻常的特性之一是 getters 的概念。这些是在运行时构造的可调用对象,用于从序列中检索对象或内容的属性。在使用迭代器或生成器序列时,getter 特别有用,它们的开销比 lambda 或python 函数少。

operator_attrgetter.py

from operator import *
class myobj:
    """example class for attrgetter"""
    def __init__(self, arg):
        super().__init__()
        self.arg = arg
    def __repr__(self):
        return 'myobj({})'.format(self.arg)
l = [myobj(i) for i in range(5)]
print('objects   :', l)
# 从每个对象中提取 'arg' 值
g = attrgetter('arg')
vals = [g(i) for i in l]
print('arg values:', vals)
# 使用 arg 排序
l.reverse()
print('reversed  :', l)
print('sorted    :', sorted(l, key=g))

属性 getter 的工作方式类似于 lambda x,n ='attrname':getattr(x,n)

$ python3 operator_attrgetter.py
objects   : [myobj(0), myobj(1), myobj(2), myobj(3), myobj(4)]
arg values: [0, 1, 2, 3, 4]
reversed  : [myobj(4), myobj(3), myobj(2), myobj(1), myobj(0)]
sorted    : [myobj(0), myobj(1), myobj(2), myobj(3), myobj(4)]

项目 getter 像 lambda x, y = 5: x[y] 一样工作:

operator_itemgetter.py

from operator import *
l = [dict(val=-1 * i) for i in range(4)]
print('dictionaries:')
print(' original:', l)
g = itemgetter('val')
vals = [g(i) for i in l]
print('   values:', vals)
print('   sorted:', sorted(l, key=g))
print()
l = [(i, i * -2) for i in range(4)]
print('\ntuples:')
print(' original:', l)
g = itemgetter(1)
vals = [g(i) for i in l]
print('   values:', vals)
print('   sorted:', sorted(l, key=g))

项目 getters 使用映射和序列。

$ python3 operator_itemgetter.py
dictionaries:
 original: [{'val': 0}, {'val': -1}, {'val': -2}, {'val': -3}]
   values: [0, -1, -2, -3]
   sorted: [{'val': -3}, {'val': -2}, {'val': -1}, {'val': 0}]
tuples:
 original: [(0, 0), (1, -2), (2, -4), (3, -6)]
   values: [0, -2, -4, -6]
   sorted: [(3, -6), (2, -4), (1, -2), (0, 0)]

结合运算符和自定义类

operator 模块中的函数通过标准 python 接口进行操作,因此它们可以使用用户定义的类以及内置类型。

operator_classes.py

from operator import *
class myobj:
    """运算符重载的示例"""
    def __init__(self, val):
        super(myobj, self).__init__()
        self.val = val
    def __str__(self):
        return 'myobj({})'.format(self.val)
    def __lt__(self, other):
        """小于比较"""
        print('testing {} < {}'.format(self, other))
        return self.val < other.val
    def __add__(self, other):
        """添加值"""
        print('adding {}   {}'.format(self, other))
        return myobj(self.val   other.val)
a = myobj(1)
b = myobj(2)
print('comparison:')
print(lt(a, b))
print('\narithmetic:')
print(add(a, b))

有关每个运算符使用的特殊方法的完整列表,请参阅 python 参考指南。

$ python3 operator_classes.py
comparison:
testing myobj(1) < myobj(2)
true
arithmetic:
adding myobj(1)   myobj(2)
myobj(3)

也可以看看

  •  -- 函数式编程工具,包括 total_ordering() 装饰器,用于向类添加丰富的比较方法。
  •  -- 迭代器操作符。
  •  -- 集合的抽象类型。
  • numbers -- 数值的抽象类型。

本文章首发在 金年会app官方网 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 cc 协议,如果我们的工作有侵犯到您的权益,请及时联系金年会app官方网。

原文地址:https://learnku.com/docs/pymotw/operator...

译文地址:https://learnku.com/docs/pymotw/operator...

上一篇 下一篇
讨论数量: 0



暂无话题~
网站地图