python装饰器原理导读(内部闭包函数、装饰函数、装饰器函数&语法糖)

一、最基本的函数定义及调用
# 定义函数
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)
'''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值