[toc]
第五章 一等函数
函数是一等对象,一等对象需满足
- 在运行时创建
- 能赋值给对象或者数据结构中的元素
- 能作为参数传递给函数
- 能作为函数的返回结果
在Python中,整数、字符串、字典等都是一等对象,函数也是一等对象,只是把函数视作一等对象的时候,简称为一等函数。
把函数视作对象
函数也是对象,本身是function类的实例
高阶函数
接受函数作为参数,或者把函数作为返回结果的函数叫做高阶函数。常见的高阶函数有map,filter,sorted等,其中map和filter返回的是生成器。
all和any的用法:
- all(iterable),如果iterable的每个元素都是真值则返回True,all([])返回True
- any(iterable),只要iterable有元素为真则返回true,all([])返回False
可调用对象
能使用()的都被叫做可调用对象,可使用callable()判断一个对象是否是可调用对象,python中有7中可调用对象:
- 用户定义的函数
- 内置函数
- 内置方法
- 方法
- 类,调用时会运行
__new__方法创建一个实例,然后运行__init__方法初始化实例,最后把实例返回给调用方。 - 类的实例,前提是类定义了
__call__方法。 - 生成器函数,在函数中使用了
yieled语句的
用户定义的可调用类型
只需实现__call__方法。
例子,从打乱的列表中取出一个元素1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import random
calss BingoCage:
def __init__(self,items):
self._items = list(items)
random.shuffle(self._items)
def pick(self):
try:
return self._items.pop()
except IndexError:
raise LookupError('pick from empty BingCage')
def __call__(self):
return self.pick()
1 | bingo = BingoCage(range(6)) |
函数内省
Wikipedia内省)的定义:
内省是指计算机程序在运行时(Run time)检查对象(Object)类型的一种能力,通常也可以称作运行时类型检查。
通俗来讲就是Python在运行时能够知道这个对象是什么,它能做什么,它包含哪些内容。
一些内省函数:
dir(object):它返回一个列表,这个列表中包含object的所有属性type:返回一个对象的类型id:返回一个对象的id
获取关于参数的信息
函数对象有个__defaults__属性,它的值是一个元组,里面保存着定位参数和关键字参数的默认值。__kwdefaults__包含仅限关键字参数的默认值。参数的名称在__code__属性中,它的值是一个code对象引用。
函数注解
函数声明中的各个参数可以在:之后增加注解表达式。如果参数有默认值放在参数名和=之间。如果想添加返回值注解,在)和函数声明末尾:之间添加->和一个表达式。
注解存储在__annotations__属性中
支持函数式编程的包
operator
itmegetter和attrgetter会自行构建函数,所起的作用类似于使用lambda表达式从序列中取出元素或者读取对象的属性。
itemgetter
下例利用itemgetter排序一个数组,itemgetter()的作用与lambda fields: fields[1]相同,创建一个接收集合的函数,返回索引位1的元素。
1 | metro_data = [('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),] |
attrgetter
它创建的函数根据名称提取对象的属性,如果把多个属性名传给attrgetter,它也会返回提取的值构成的元组。
例子1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16from collections import namedtuple
LatLong = namedtuple('LatLong', 'lat long')
Metropolis = namedtuple('Metropolis', 'name cc pop coord')
metro_areas = [Metropolis(name, cc, pop, LatLong(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
35.689722
from operator import attrgetter
name_lat = attrgetter('name','coord.lat')
for city in sorted(metro_areas,key=attrgetter('coord.lat')):
print(name_lat(city))
...
('Sao Paulo', -23.547778)
('Delhi NCR', 28.613889)
('Tokyo', 35.689722)
methodcaller
methodcaller创建的函数会在对象上调用参数指定的方法。
例子1
2
3
4
5
6from operator import methodcaller
s = 'good good study, day day up'
upcase = methodcaller('upper')
upcase(s)
'GOOD GOOD STUDY, DAY DAY UP'
>>>
使用functools.partial冻结参数
functools.partial这个高阶函数用于部分应用一个函数。部分应用指的是,基于一个函数创建一个新的可调用对象,把原函数的某些参数固定。
例子1
2
3
4
5from operator import mul
from functools import partial
triple = partial(mul,3)
[triple(i) for i in range(6)]
[0, 3, 6, 9, 12, 15]
