python基础装饰器_Python基础 —— 装饰器函数

装饰器函数

导航

装饰器的形成过程

装饰器的功能了解

importtimedeffunc1():print("in func1")deftimer(func):definner():

start=time.time()

func()print(time.time()-start)returninner

func1=timer(func1)

func1()'''timer(func1)() --> 即执行的是 inner()

输出:

in func1

0.0'''

装饰器 - 简单版

需要在目标的执行函数上加一次赋值调用。

装饰器的语法糖

deftimer(func):definner():

start=time.time()

func()print(time.time() -start)returninner

@timerdef func1(): #==> func1 = timer(func1)

print("in func1")

func1()

装饰器 - 语法糖

总结

装饰器的本质:一个闭包函数

装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

装饰一个带参数的函数

deftimer(func):def inner(a): ###

start =time.time()

func(a)###

print(time.time() -start)returninner

@timerdef func1(a): ###

print("in func1" +a)

func1("hello world")

被装饰函数需要传参

不同函数需要不同的参数,但又需要同一个功能的装饰器。

ef timer(func):def inner(*args, **kwargs):print("函数开始执行")

func(*args, **kwargs)print("函数执行结束")returninner

@timerdeffunc1(name):print("..." +name)

@timerdeffunc2(age):print("年龄:",age)

func1("Clare")

func2(18)'''函数开始执行

...Clare

函数执行结束

函数开始执行

年龄: 18

函数执行结束'''

一次性hold住所有函数传参

带返回值的装饰器

deftimer(func):def inner(*args, **kwargs):

ret= func(*args, **kwargs)return ret ###

returninner

@timerdeffunc1(name):return "姓名:%s" %name

res= func1("Clare")print(res)'''姓名:Clare'''

被装饰函数有返回值

查看函数信息的方法失效及问题解决

deftimer(func):def inner(*args, **kwargs):

ret= func(*args, **kwargs)returnretreturninner

@timerdeffunc1():'''这是一个func1'''

return "in func1"

print(func1.__doc__) #查看函数注释:None

print(func1.__name__) #inner,执行func1实际是执行:timer(func1)(),即inner()

############# 对比 #############

deffunc2():'''这是一个func1'''

return "in func1"

print(func2.__doc__) #查看函数注释:"这是一个func1"

print(func2.__name__) #func2

查看函数信息的方法失效

from functools importwrapsdeftimer(func):

@wraps(func)def inner(*args, **kwargs):

ret= func(*args, **kwargs)returnretreturninner

@timerdeffunc1():'''这是一个func1'''

return "in func1"

print(func1.__doc__) #这是一个func1

print(func1.__name__) #func1

解决方法:@wraps(func)

装饰器的主要功能和固定结构

装饰器的主要功能

在不改变函数调用方式的基础上在函数的前、后添加功能。

装饰器的固定结构

defwrapper(func):def inner(*args, **kwargs):'''执行函数之前要进行的操作'''ret= func(*args, **kwargs)'''执行函数之后要进行的操作'''

returnretreturn inner

from functools importwrapsdefwrapper(func):

@wraps(func)#最内层函数上方

def inner(*args, **kwargs):

ret= func(*args, **kwargs)returnretreturn inner

wraps(func) 固定结构

带参数的装饰器

如果说很多个函数共同使用了一个装饰器,现需要取消掉装饰器的功能。万一去掉之后又需要加上,工作量太过繁重。

或者说某几个函数仍需要该装饰器,而另外几个函数暂时性的不需要呢。

defouter(flag):defwrapper(func):def inner(*args, **kwargs):ifflag:print('''执行函数之前要进行的操作''')

ret= func(*args, **kwargs)ifflag:print('''执行函数之后要进行的操作''')returnretreturninnerreturnwrapper############## 不需要被装饰 ###########

@outer(False)deffunc():print("in func")

func()#in func

############## 需要被装饰 ###########

@outer(True)deffunc():print("in func")

func()'''执行函数之前要进行的操作

in func

执行函数之后要进行的操作'''

控制函数是否需要被装饰

多个装饰器装饰同一个函数

defwrapper1(func):def inner(*args, **kwargs):print("wrapper1")

ret= func(*args, **kwargs)print("wrapper1")returnretreturninnerdefwrapper2(func):def inner(*args, **kwargs):print("wrapper2")

ret= func(*args, **kwargs)print("wrapper2")returnretreturninner

@wrapper2#func1 = wrapper2(wrapper1(func))

@wrapper1 #func1 = wrapper1(func)

deffunc():print("func")

func()'''wrapper2

wrapper1

func

wrapper1

wrapper2'''

多个装饰器装饰同一个函数的执行顺序

一个装饰器时可以简写为return func(*args, **kwargs)

多个装饰器时,不能简写,不会执行return后的代码

ret= func(*args, **kwargs)return ret

注意

#####################################

一、解耦

要完成一个完整的功能,但这个功能的规模要尽可能小,并且和这个功能无关的其他代码应该和这个函数分离

# 1、增强代码的可读性

# 2、减少代码变更的重复影响

1 deffunc():2 whileTrue:3 print("从前有座山,山里有座庙,庙里有个老和尚在讲故事,故事是这样的:")4

5 func()

# 运行结果:会无休止的打印该字符串,没有结束。

1 deffunc():2 print("从前有座山,山里有座庙,庙里有个老和尚在讲故事,故事是这样的:")3

4 for i in range(10):5 func()#打印该字符串十次。修改range里的数值可控制打印次数。

二、递归

什么是递归:

# 1、一个函数在自己内部调用自己。

# 2、递归的层数在python里是有限制的。(997/998层)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值