python-函数及高阶函数

函数中return默认返回None,若指定了多个返回值,则封装成一个元组

函数参数

参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
def person(name, age=18, *args, city, **kw):

默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
可变参数*args既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过*args传入:func(*(1, 2, 3));
关键字参数**kwargs既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过**kw传入:func(**{'a': 1, 'b': 2})。
命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。定义命名的关键字参数在没有可变参数的情况
下不要忘了写分隔符*,否则定义的将是位置参数。(未知参数?)(所以命名的关键字参数是一种特殊的关键字参数)

有多个默认参数时,调用的时候,既可以按顺序提供默认参数,也可以不按顺序提供部分默认参数。

作用域(搜索优先级顺序:LEGB)

local,局部作用域,即函数中的变量
enclosing,嵌套的腹肌函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的
global,全局变量,就是模块级别定义的变量
built-in,系统固定模块里的变量

递归函数

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。
遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。
实验结果:递归不能超出997层?

但凡递归可以写的程序,循环都可以解决。
递归的效率很低

lambda表达式

lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。
# 定义函数(lambda表达式)冒号前面是参数,冒号后面是返回值,返回值可以是表达式;无中间过程
my_lambda = lambda arg : arg + 1

高阶函数

把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
map/reduce/filter
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

闭包

一般情况下,我们定义一个函数。调用该函数时,会结果一系列计算,返回最终结果。

但是有时我们不需要立刻求和,而是在后面的代码中,根据需要在计算怎么办
这时可以定义2层函数,外层函数返回值为内层函数的函数名---这就是闭包
注意:调用外层函数返回内层函数名时,外层函数的相关参数和变量都已经保存在了返回的内层函数中
每次调用外层函数返回的内层函数都是不同的,即使外层函数的参数变量完全一致

闭包函数:2个条件
1,一个函数中定义有一个内部函数
2,这个内部函数对外部函数的变量进行引用

简单来说就是闭包函数作为一个内部函数,却可以在全局被调用

装饰器

本质上,decorator(装饰器)就是一个返回函数的高阶函数。
把@log放到now()函数的定义处,相当于执行了语句:now = log(now)

有时需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。
不需要编写wrapper.__name__ = func.__name__这样的代码,Python内置的functools.wraps就是干这个事的

装饰器,加深理解:对一个函数增加了计时功能,同时还是用原函数实现
import time
def outer(aaa):
def inner():
start = time.time()
aaa()
time.sleep(2)
sun1 = time.time() - start
return sun1
return inner
@outer #与abc = outer(abc)完全等价,但是在原定义函数的上方
def abc():
print('输出是:')

abc = outer(abc)
print(abc)
print(abc())

偏函数

functools.partial就是帮助我们创建一个偏函数的,
int2 = functools.partial(int, base=2)
与下面的等效
def int2(x, base=2):
return int(x, base)
简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

猜你喜欢

转载自www.cnblogs.com/AllenWoo/p/9384842.html