函数即变量
定义一个函数就是把函数体给函数名。变量先定义后使用,函数一定要先声明后调用,只要声明后调用即可,哪个先定义哪个后定义没有关系。如图所示:
高阶函数
所谓高阶函数就是1. 把一个函数名当作实参传给另一个参数;2.把函数作为结果值返回。
1. 传入参数
# 高阶函数
import time
def a():
time.sleep(2)
print("hello,I am a")
def b(fun):
start_time = time.time()
fun() # 此处不要写成fun
stop_time = time.time()
print("the function time is %s" %(stop_time - start_time))
b(a) # 像变量一样传入函数名即可,不要写成b(a())
2. 返回函数
# 高阶函数
import time
def a():
start_time = time.time()
time.sleep(2)
stop_time = time.time()
print("the function time is %s" %(stop_time - start_time))
def b(fun):
return fun # 返回函数
f = b(a) # 当我们调用b(a)时,返回的并不是结果,而是函数本身
f() # 调用函数
嵌套函数
嵌套不等于调用,即:
def b():
def a():
和
def b():
a()
不一样
可以把内部嵌套函数看作是局部变量。
装饰器
装饰器:本质上是函数,功能是装饰函数,也就是为其他函数增加新功能。在代码运行期间动态增加功能的方式叫做装饰器。
原则:
1.不能修改被装饰函数的源代码。
2.不能修改被装饰函数的调用方式。
装饰器 = 高阶函数 + 嵌套函数
import time
import functools
def b(func):
@functools.wraps(func)
def a():
start_time = time.time()
func()
stop_time = time.time()
print("the function time is %s" %(stop_time - start_time))
return a
@b # old = b(old)
def old(): # 被装饰函数
time.sleep(2)
print("hello,我是原来函数")
old()
满足了不改动原函数和调用方法的原则。
闭包
其实用的还是高阶函数,不是立马返回结果,而是返回函数本身。
1.
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”。
我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数。返回的函数并没有立刻执行,而是直到调用了才会执行。
2.
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count() # 列表里的三个函数,调用时才会执行
print(f1())
print(f2())
print(f3())
结果并不是1,4,9,原因就在于返回的函数引用了变量i,但它并非立刻执行,等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果都为9。