高阶函数
在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:
接受一个或多个函数作为输入
输出一个函数
在数学中它们也叫做算子(运算符)或泛函。微积分中的导数就是常见的例子,因为它映射一个函数到另一个函数。
在无类型lambda演算,所有函数都是高阶的;在有类型lambda演算(大多数函数式编程语言都从中演化而来)中,高阶函数一般是那些函数型别包含多于一个箭头的函数。在函数式编程中,返回另一个函数的高阶函数被称为Curry化的函数。
在很多函数式编程语言中能找到的map函数是高阶函数的一个例子。它接受一个函数f作为参数,并返回接受一个列表并应用f到它的每个元素的一个函数。
高阶函数的其他例子包括函数复合、积分和常量函数λx.λy.x。
函数名称也是一个变量,f是一个函数,调用f,a,b默认是整型
##已知一个函数:
In [11]: def f(n):
...: return n*n
...: print(f(3))
...:
9
##调用已有函数:
注:foo传入三个变量,a,b传入是整数,func传入是一函数f,就会执行f,func(a),func(b)时会分别传入1,2这两个参数
In [12]: def foo(a,b,func):
...: ret=func(a)+func(b) #f(a)+f(b)
...: return ret
...: print(foo(1,2,f)) #f传入是函数的名称,相当于是func,相当于a接收1,b接收2
...:
5
注:变量赋值,正规描述是对象引用,对象是2,被a引用,b=a后,b也引用了2
函数存储方式
描述:如下函数,程序执行完如下两行后,没有调用,所以没有结果,实际解释器把函数存储在内存,程序没有执行之间,内存里没有这个函数,执行完后就存储了.
在内存中,print('ok')就是在内存里的一个函数对象,由函数名来引用,函数名本身就是一个变量,定义时就规划好了,叫作f,存储是函数对象的内存地址,变量与函数不一样时,变量直接使用,函数要调用时要使用括号f(),所以f就是一个变量名字,它存储的内存地址就是函数对象的内存地址,所以函数本身是一个对象,函数的名称是一个是一个变量,变量是可以赋值的,可以重新赋值foo=f,这样这个函数对象就有两个引用,无论执行那个,对应的代码块都会相应执行
summary:
a.函数名字可以进行赋值
In [1]: def f():
...: print('ok')
...:
In [2]: foo=f
b.函数名字是一个变量,可以作为一个参数,还可以作为函数的返回值
描述:定义一个函数bar,其中a,b是一个变量的名字,bar(1,2)调用时可以传值,a,b是一个参数,1,2是整型,如果再写一个bar(a,b,func),func可以是一个函数对象,调用时可以放入一个函数f,f是一个变量,但是通过这个函数名可以去调用相应的代码块,可以在bar函数执行调用时的func,调用func(),实际是调用bar函数,这个函数传入1,2两个整型对象,分别赋值给a,b,还添加函数f,把f传入后就可以执行对应的代码块func()
In [3]: def bar(a,b,func):
...: func()
...: return 1
In [4]: bar(1,2,f)
ok
Out[4]: 1
函数名称作为函数返回值
变量
In [5]: def foo2():
...: x=5
...: return x
In [6]: foo2() #调用foo2时,返回是x变量,x指向是5
Out[6]: 5
函数
描述:如果调用时使用inner(),inner无论什么时候出现,后面只要有(),它就会去执行函数,所以当执行foo3时,先把def inner()的内容存到内存,会直接返回一个执行结果,在return之前发现一个函数执行了,首先会执行函数inner(),函数已经在内存,inner()相当于8,foo3调用了return,但是inner()这种情况一般不会用,是希望返回一个函数名字inner,返回后是foo3调用的结果得到,实际inner是一个函数对象的引用,这样返回的是一个函数对象的内存地址
In [8]: def foo3():
...: def inner():
...: return 8
...: return inner() ##调用函数
...: foo3()
...:
Out[8]: 8
In [7]: def foo3():
...: def inner():
...: return 8
...: return inner ##函数名称
...: foo3()
...:
Out[7]: <function __main__.foo3.<locals>.inner> ##实际是一个对象引用
In [10]: ret=foo3()
In [11]: ret() ##要执行inner函数的内容,先赋值,再使用()调用
Out[11]: 8
注:不是函数内容,是函数对象,变量是一个内存地址,存储是函数对象的内存地址