一、最基本的函数定义及调用
# 定义函数
def demo():
print('hello')
# 调用函数
demo()
二、需求:统计每个函数的执行时间
-
计算指定函数运行时间
-
方法一:一个函数内完成
import time
def func1():
start = time.time()
print('in func1')
time.sleep(5)
end = time.time()
print(end-start)
func1()
-
如果每个函数都要输入一套计算执行时间的代码,工作将是巨大的.这种方法是不值得提倡的。
-
方法二:两个函数协助完成
import time
def func1():
start = time.time()
print('in func1')
time.sleep(5)
# 这里的‘func参数’和‘func1函数’具有本质的不同
def timer(func):
start = time.time
func() # 传递函数地址,代表函数的调用
end = time.time()
print(end-start)
timer(func1)
# 在调用timer函数时,必须传递实参,而不是func形参
- 方法三
import time
def func1():
start = time.time()
print('in func1')
time.sleep(5)
# 这里的‘func参数’和‘func1函数’具有本质的不同
def timer(func): #这是外部函数
def inner(): #这是内部函数
#闭包函数:内部函数使用了外部函数,内部函数就是一个闭包函数;
start = time.time
func() # 传递函数地址,代表函数的调用
end = time.time()
print(end-start)
return inner #如果返回inner() 加上括号就表示对函数的调用,返回的还是空值,所以只能返回 inner, 这表示返回 inner闭包函数的地址。
func1 = timer(func1) #这一步是关键:地址的改变;
func1()
# 方法详解
# 第一步:先看右边的timer(),它对应了一个地址;
# 第二步:左边的func1()原来也有自己的一个地址;
# 第三步:func1 = timer(),就是让func1()的地址指向了timer()的地址;
# 第四步:调用func1(),就会进入timer()函数并执行,
# 第五步:【问题】当执行timer函数时,timer内的参数func没有传递实参,无法执行,
# 所以要在timer()内加入func1
# 第六步:【问题】有了实参继续向下执行完毕后,timer()函数的没有返回值,
# 因此,func1=timer(func1)最后会报错:“TypeError:‘Nonetype’object is not callable”
# -->无类型的对象不可调用,所以要给timer()函数一个返回值。
# 第七步:在timer函数下,再定义一个函数inner(),这个函数为闭包函数;
# 然后return inner,表示返回一个地址。
# 第八步:这时,调用func1()函数后,会执行timer()内部的inner(),并返回inner函数的地址;并且func1成功输出。
- 方法四
import time
# 使用装饰器函数,前提是将装饰函数放在被装饰函数前面;
def timer(func): #这是外部函数=装饰函数;外号:“传参函数”
def inner(): #这是内部函数=闭包函数;外号:“判断执行函数”
start = time.time()
func()
end = time.time()
print(end-start)
return inner
@timer # 装饰器函数/语法糖
def func2(): # 被装饰函数
print('in func1')
time.sleep(3)
# func2 = timer(func2)
func2()
'''
1.func2 = timer(func2) ,这一步很多人很难理解,所以可以暂且注释掉;
2.同时,在装饰函数前面加上 @timer 装饰器/语法糖;
3.这个@timer 装饰器,等同于 func2 = timer(func2)
'''