operator模块
operator: 模块提供了很多python内置运算符对应的函数。 比如加,减,乘,除,与,或,非,is, is not等等。
此模块存在的意义:有时我们在函数式编程时,经常要将一个函数传递给另一个函数。对于像加,减,乘,除这些我们当然可以自定义一个函数,或使用lambda函数来做为参数传递,但这样在性能上不如使用operator模块里的内置函数。
下面是一个性能对比:
PS> python -m timeit "(lambda a, b: a + b)(10, 10)"
5000000 loops, best of 5: 82.3 nsec per loop
PS> python -m timeit -s "from operator import add" "add(10, 10)"
10000000 loops, best of 5: 24.5 nsec per loop
PS> python -m timeit "10 + 10"
50000000 loops, best of 5: 5.19 nsec per loop
PS> python -m timeit "(lambda a, b: a ** b)(10, 10)"
1000000 loops, best of 5: 226 nsec per loop
PS> python -m timeit -s "from operator import pow" "pow(10, 10)"
2000000 loops, best of 5: 170 nsec per loop
PS> python -m timeit "10 ** 10"
50000000 loops, best of 5: 5.18 nsec per loop
示例使用了一个两数相加的简单例子做性能对比,结果是,内置运算符 > operator内置函数 > lambda函数或自定义函数。
列举几个operator模块函数与运算符的关系:
a + b对应add(a, b),
seq1 + seq2对应concat(seq1, seq2),
obj in seq对应contains(seq, obj),
a < b对应lt(a, b)。
很多运算符有其对应的in-place版本,比如:
a += b对应iadd(a, b),
a %= b对应imod(a, b)
还有些下标访问及修改和删除的操作:
obj[k] = v对应setitem(obj, k, v)
del obj[k]对应delitem(obj, k)
obj[k]对应getitem(obj, k)
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))
另外还有方法没有对应的操作符与之对应:
operator.call(obj, /, *args, **kwargs)
operator.indexOf(a, b)
operator.countOf(a, b)
而我们在实际中可能更常用到的是下面三个函数:
itemgetter: 参数用于接收索引,返回一个函数,函数接收一个对象。执行时,返回对象对应的索引位置的值。 函数签名有两种itemgetter(item)和itemgetter(*items)。
此方法相当于一个带参数的装饰器,参数用于接收索引,返回的函数可作用于任何能够索引的对象,比如sequences, mappings类型。
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'
attrgetter: 此方法用法与itemgetter类似,接收一个或多个属性名(两种签名:attrgetter(attr), attrgetter(*attrs)),返回的函数作用于任何对象,用以返回该对象对应的属性值。
from dataclasses import dataclass
@dataclass
class Musician:
name: str
age: int
harry = Musician('Harry', 12)
from operator import attrgetter
get_age = attrgetter('age')
get_name_age = attrgetter('name','age')
print(get_age(harry)) # 12
print(get_name_age(harry)) # ('Harry', 12)
methodcaller: 此方法与attrgetter类似,只不过用于返回一个对象的方法,而不是属性。签名为 methodcaller(name, /, *args, **kwargs)
from dataclasses import dataclass
@dataclass
class Musician:
name: str
age: int
def self_introduce(self):
return f"My name is {self.name}, I'm {self.age} years old"
harry = Musician('Harry', 12)
from operator import methodcaller
get_introduce = methodcaller('self_introduce')
print(get_introduce(harry)) # My name is Harry, I'm 12 years old

浙公网安备 33010602011771号