Python标准库之operator

本模块主要包括一些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

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)

operator的使用

attrgetter

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

  • After f = attrgetter(‘name’), the call f(b) returns b.name.
  • After f = attrgetter(‘name’, ‘date’), the call f(b) returns (b.name, b.date).
  • After f = attrgetter(‘name.first’, ‘name.last’), the call f(b) returns (b.name.first, b.name.last).

我们通过下面这个例子来了解一下itergetter的用法:

>>> class Student:
...     def __init__(self, name, grade, age):
...         self.name = name
...         self.grade = grade
...         self.age = age
...     def __repr__(self):
...         return repr((self.name, self.grade, self.age))
>>> student_objects = [
...     Student('john', 'A', 15),
...     Student('jane', 'B', 12),
...     Student('dave', 'B', 10),
... ]
>>> sorted(student_objects, key=lambda student: student.age)   # 传统的lambda做法
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
>>> from operator import itemgetter, attrgetter
>>> sorted(student_objects, key=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
# 但是如果像下面这样接受双重比较,Python脆弱的lambda就不适用了
>>> sorted(student_objects, key=attrgetter('grade', 'age'))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

attrgetter的实现原理:

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

attritem 提取对象的属性。

attritemitemgetter相似 
namedtupletuple的子集。提供了一个类似元祖的数据结构,并声明空的属性。

collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)

 两者的关系相当于下标用字符串和数字去访问。

>>> from collections import namedtuple
>>> LatLong = namedtuple('LatLong', 'lat long')  # 定义 LatLong
>>> Metropolis = namedtuple('Metropolis', 'name cc pop coord')  # 再定义 Metropolis
>>> metro_areas = [Metropolis(name, cc, pop, LatLong(lat, long))  # 使用嵌套的元组拆包提取 (lat, long)
...     for name, cc, pop, (lat, long) in metro_data]
>>> metro_areas[0]
Metropolis(name='Tokyo', cc='JP', pop=36.933, coord=LatLong(lat=35.689722,
long=139.691667))
>>> metro_areas[0].coord.lat  # 深入 metro_areas[0],获取它的纬度。
35.689722
>>> from operator import attrgetter
>>> name_lat = attrgetter('name', 'coord.lat')  # 定义一个 attrgetter,获取 name 属性和嵌套的 coord.lat 属性。
>>>
>>> for city in sorted(metro_areas, key=attrgetter('coord.lat')):  # 使用 attrgetter,按照纬度排序城市列表。
...     print(name_lat(city))  # 使用定义的 attrgetter city,只显示城市名和纬度。
...
('Sao Paulo', -23.547778)
('Mexico City', 19.433333)
('Delhi NCR', 28.613889)
('Tokyo', 35.689722)
('New York-Newark', 40.808611)

itemgetter

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

  • After f = itemgetter(2), the call f(r) returns r[2].
  • After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3]).

我们通过下面这个例子来了解一下itergetter的用法:

>>> student_tuples = [
...     ('john', 'A', 15),
...     ('jane', 'B', 12),
...     ('dave', 'B', 10),
... ]
>>> sorted(student_tuples, key=lambda student: student[2])   # 传统的lambda做法
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
>>> from operator import attrgetter
>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
# 但是如果像下面这样接受双重比较,Python脆弱的lambda就不适用了
>>> sorted(student_tuples, key=itemgetter(1,2))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

itemgetter的实现原理

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

使用 itemgetter 排序一个元组列表。

itemgetter(num) 指定一个位置。

>>> metro_data = [
...     ('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),
...     ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
...     ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
...     ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
...     ('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),
... ]
>>>
>>> from operator import itemgetter
>>> for city in sorted(metro_data, key=itemgetter(1)):
...     print(city)
...
('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833))
('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889))
('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
('Mexico City', 'MX', 20.142, (19.433333, -99.133333))
('New York-Newark', 'US', 20.104, (40.808611, -74.020386))
>>> cc_name = itemgetter(1, 0)
>>> for city in metro_data:
...     print(cc_name(city))
...
('JP', 'Tokyo')
('IN', 'Delhi NCR')
('MX', 'Mexico City')
('US', 'New York-Newark')
('BR', 'Sao Paulo')

methodcaller

operator.methodcaller(name[, args…])

  • After f = methodcaller(‘name’), the call f(b) returns b.name().
  • After f = methodcaller(‘name’, ‘foo’, bar=1), the call f(b) returns b.name(‘foo’, bar=1).

methodcaller的实现原理:

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

猜你喜欢

转载自blog.csdn.net/q389797999/article/details/81880618