函数(下)
高阶函数
高阶函数的定义:
1.此函数传入或接收的参数是一个函数名
2.此函数的返回值是一个函数名
3.满足上述两个条件中任意一个,都可称之为高阶函数
实例
函数名作为参数
def test1():
print('this is test one')
def test(func):
t=test1()
print(t)
test(test1)
函数名作为返回值
def test():
print('test')
return test
x=test()
print(x())
函数名作为参数且返回函数名
def test1():
print('this is test one')
def test(func):
print('func name is '+func.__name__)
return func
x=test(test1)
x()
高阶函数调用
def add(x,y):
return x+y
def subtract(x,y):
return x-y
def mytest(x,y,f):#形参f的类型为函数对象
return f(x,y)
a,b=5,2
print('参数1为%d,参数2位%d,结果位%d'%(a,b,mytest(a,b,add)))
print('参数1为%d,参数2为%d,结果为%d'%(a,b,mytest(a,b,subtract)))
匿名函数
lambda函数的语法只包含一个语句,如下: lambda arg1,arg2,…argn:expression
示例:
普通python函数
def func(a,b,c):
return a+b+c
print func(1,2,3)
返回值为6
lambda匿名函数
f = lambda a,b,c:a+b+c
print f(1,2,3)
返回结果为6
f = lambda a,b,c:a+b+c 中的关键字lambda表示匿名函数,
冒号:之前的a,b,c表示它们是这个函数的参数。
匿名函数不需要return来返回值,表达式本身结果就是返回值。
闭包
闭包的理解
闭包是一种特殊的函数,这种函数由两个函数的嵌套组成,且称之为外函数和内函数,外函数返回值是内函数的引用,此时就构成了闭包。
闭包的格式
def 外层函数(参数):
def 内层函数():
print("内层函数执行", 参数)
return 内层函数
内层函数的引用 = 外层函数("传入参数")
内层函数的引用()
实例
def func(a, b):
def line(x):
return a * x - b
return line
line = func(2, 3)
print(line(5))
结果得到 7
在这个实例中,外函数func有接收参数 a=2,b=3,内函数line接收参数x=5,在内函数体中计算了a*x-b 即 2×5-3的值作为返回值,外函数返回内函数的引用,这里的引用指的是内函数line在内存中的起始地址,最终调用内函数line()得到返回值7
内函数中修改外函数的值
使用 nonlocal 关键字声明变量
def func(a, b):
def line(x):
nonlocal a
a = 3
return a * x - b
return line
line = func(2, 3)
print(line(5))
此时运行结果为:12
闭包的用途
Python中,闭包的主要用途就是用于装饰器的实现
装饰器
装饰器本质就是函数,功能是为其他函数添加附加功能。
原则: 不修改被修饰函数的源代码 不修改被修饰函数的调用方式。
装饰器=高级函数+函数嵌套+闭包
简易装饰器
实例:
def dmeo(func):
print("简易装饰器测试-开始")
func()
print("简易装饰器测试-结束" )
def func():
print("hello")
print("world")
f = func
dmeo(f)
不定参数装饰器
实例:
def dmeo(func):
def wrapper(*args, **kwargs):
print("不定参数装饰器测试-开始")
func(*args, **kwargs)
print("不定参数装饰器测试-结束" )
return wrapper
@dmeo
def func(a,b):
print("原函数1-开始:")
print("原函数1-结束 %d" %(a+b))
@dmeo
def func2(a,b,c):
print("原函数2-开始:")
print("原函数2-结束 %d " %(a+b+c))
f = func
func2(3,4,5)
f(3,4)
命名空间
命名空间分为内置命名空间、全局命名空间和局部命名空间
内置命名空间:
python解释器一启动就可以使用的名字,内置的名字再启动解释器后被加载进内存中;
全局命名空间:
在程序从上至下依次执行时被加载进内存,这个空间放置了我们大部分变量名及函数名;
局部命名空间:
即函数内部定义的名字,当调用函数是产生,随着函数执行的结束而结束。
在局部可以使用全局、内置及本地局部的命名空间的名字,在全局只能使用全局及内置名字,内置亦然。在命名空间中找名字,从当前空间往外寻找,如果从局部开始,本地局部没有则找全局,全局没有则找内置,如果内置也没有则会报错,如果有则在找到的那一刻结束查找。注意:局部与局部之间命名空间各自独立,相互分离。