在python中,函数是一等对象。编程语言理论上把一等对象定义满足以下条件的程序实体:
- 在运行时创建
- 能赋值给变量或数据结构中的元素
- 能作为参数传递给函数
- 能作为函数返回结果
在python中,整数,字典,字符串都是一等对象。
把函数视作对象
python函数是对象
>>> def func():
... return 'hello word'
...
>>> func()
'hello word'
>>> func.__doc__
>>> type(func)
<class 'function'>
高阶函数
接受函数为参数,或者把函数作为结果返回的函数就是高阶函数。例如,map,filter,reducee,
sum 和 reduce 的通用思想是把某个操作连续应用到序列的元素上,累计之前的结果,把一系列值归约成一个值。all 和 any 也是内置的归约函数。
1)all(iterable)
如果 iterable 的每个元素都是真值,返回 True;all([]) 返回True。
2)any(iterable)
只要 iterable 中有元素是真值,就返回 True;any([]) 返回 False。
匿名函数
lambda关键字创建匿名函数,缺点:定义中不能赋值,不能使用while和try等其它python语句,一及不易读,优点是在一些小功能上使用lambda会更清爽
lambda重构秘籍
- 编写注释,说明lambda表达式的作用
- 研究一会儿注释,并找出一个名称来概括注释
- 把lambdz表达式换成def语句。
- 删除注释
- List item
可调用对象
除了用户自定义的函数,调用运算符()还可以应用到其它对象上,如果想判断对象是否可调用,可以使用内置的callable()函数,
- 用户自定义的函数
使用def或者lambda创建 - 内置函数
使用c语言实现的函数,如:len - 内置方法
使用c语言实现的方法,如:dict.get - 方法
在类的定义中定义的函数 - 类
调用类时会运行类的 new 方法创建一个实例,然后运行 init 方法,初始化实例,最后把实例返回给调用方。因为 Python 没有 new 运算符,所以调用类相当于调用函数。 - 类的实例
如果类定义了 call 方法,那么它的实例可以作为函数调用 - 生成器函数
使用 yield 关键字的函数或方法。调用生成器函数返回的是生成器对象。
# 使用callable判断对象是否可以被调用
>>> [callable(obj) for obj in (abs,str,12)]
[True, True, False]
>>>
用户自定义的可调用类型
不仅 Python 函数是真正的对象,任何 Python 对象都可以表现得像函数。为此,只需实现实例方法 call。
函数内省
除了 doc,函数对象还有很多属性。使用 dir 函数可以探知其它属性。
>>> class D:
... pass
...
>>> obj = D()
>>> def func():
... pass
...
>>> sorted(set(dir(func)) - set(dir(obj))) # 计算差集,得出函数有而实例没有的属性
['__annotations__', '__call__', '__closure__', '__code__', '__defaults__', '__get__', '__globals__', '__kwdefaults__', '__name__', '__qualname__']
>>>
从定位参数到仅限关键字参数
仅限关键字参数是 Python 3 新增的特性。它一定不会捕获未命名的定位参数。定义函数时若想指定仅限关键字参数,要把它们放到前面有 * 的参数后面。如果不想支持数量不定的定位参数,但是想支持仅限关键字参数,在签名中放一个 *,如下所示:
# 中间写*号在python3.9会报错!!!
>>> def f(a, *, b):
... return a, b
...
>>> f(1, b=2)
(1, 2)
注意,仅限关键字参数不一定要有默认值,可以像上例中 b 那样,强制必须传入实参。
def f2(a, *args, c):
return a,args,c
f2(1,2,c=3)
1 (2,) 3
跟在*b后面的参数默认为关键字参数
且关键字参数必须跟在*args后面
关于获取参数的信息
函数注解
支持函数式编程
operator模块
使用functools.partial冻结函数
总结
- Python 函数的一等本性可以使我们把函数赋值给变量、传
给其他函数、存储在数据结构中,以及访问函数的属性,供框架和一些工具使用。 - 高阶函数是函数式编程的重要组成部分,即使现在不像以前那样经常使用 map、filter 和reduce 函数了,但是还有列表推导(以及类似的结构,如生成器表达式)以及sum、all 和 any 等内置的归约函数。Python 中常用的高阶函数有内置函数
sorted、min、max 和 functools. partial。 - Python 有 7 种可调用对象,从 lambda 表达式创建的简单函数到实现 call 方法的类实例。这些可调用对象都能通过内置的 callable() 函数检测。每一种可调用对象都支持使用相同的丰富句法声明形式参数,包括仅限关键字参数和注解——二者都是 Python 3 引入的新特性。
- Python 函数及其注解有丰富的属性,在 inspect 模块的帮助下,可以读取它们。例如,Signature.bind 方法使用灵活的规则把实参绑定到形参上。
- perator 模块中的一些函数,以及 functools.partial 函数,有了这些函数,函数式编程就不太需要功能有限的 lambda 表达式了。