巨人的肩膀
Python标准库之 functools/itertools/operator
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).
用法简介:
- 可以往attrgetter中传入每个参数的n个键名,以获取其值
我们通过下面这个例子来了解一下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
itemgetter
两种调用方式
operator.itemgetter(item)和operator.itemgetter(*items)
After f = itemgetter(2), the call f® returns r[2].
After g = itemgetter(2, 5, 3), the call g® returns (r[2], r[5], r[3]).
用法简介:
- 可以往itemgetter中传入每个参数的多个x位置,以获取其值
我们通过下面这个例子来了解一下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 itemgetter
>>>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
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