- 关于函数定义的单一装饰器
- 一般的通用装饰器
- 多个装饰器的使用
- 带有参数的装饰器
- 类装饰器
这是装饰器的自定义和内部机制一些初识
==***先强调装饰器的要求便是
- 不改变原来的函数代码
- 装饰器就一个函数引用参数
- 不改变调用方式***==
我先介绍一些闭包,因为装饰器也是基于闭包来实现的,区别闭包和装饰器的区别就可以看外层函数的产生个数,如果是一个并且是函数的引用是就可以看出是装饰器
#闭包
def wrapper(num):
print("开始执行外部函数")
def inner():
nonlocal num
num+=10
print(num)
return inner
demo=wrapper(10) #demo=inner
demo()
demo()
因为我这里介绍的是装饰器,闭包就提一下。
关于函数定义的单一装饰器
import time
def logging(func):
print("装饰器")
def inner():
start=time.time()
func()
end=time.time()
print("时间是%fs"%(end-start))
return inner
@logging
def say():
print("我在说话")
say() #相当于inner()
上面的@其实内部过程就是say=logging(say),装饰过后的say其实变成了inner,这里可以通过debug去看看
一般的通用装饰器
一般的通用装饰器就是可以传入不定长度的参数,还有不管是否返回值,具体见下面的代码,有其他什么问题可以直接留言
#一般的通用装饰器就是可以传入不定长度的参数,还有不管是否返回值,具体见下面的代码
def decorator(func):
print("进入了装饰器")
def inner(*args,**kwargs):
print("使用不定长度一般话")
result=func(*args,**kwargs)
return result
return inner
@decorator
def add_num(num1,num2):
return num2+num1
@decorator
def add_three_num(num1,num2,num3):
return num1+num2+num3
result=add_num(1,4)
print("add后%d"%result)
result=add_three_num(1,2,3)
print(result)
多个装饰器的使用
下面介绍一下多个装饰器的使用
这个地方遇到第一个装饰器是他先运行第二个装饰器,因为装饰器是装饰函数的,第一个make_div下面是@make_p,所以会先执行make_p的装饰器
,执行@make_p的过程就像 我前文说的echo=make_p(echo),所以现在的echo指向了make_p里面的inner,所以上面一个装饰器在装饰的时候执行的func是指向make_p里面的inner函数,这里我有个一个视频,如果大家要生动了解的话,私信我,我发给你
def make_div(func):
def inner(word):
word="<div>"+func(word)+"</div>"
return word
return inner
def make_p(func):
def inner(word):
return "<p>"+func(word)+"</p>"
return inner
@make_div
@make_p
def echo(word):
return word
print(echo("我们一起学习,加油!!"))
带有参数的装饰器
带有参数的装饰器其实就是在我们上面的装饰器外部封装一个函数,在外面函数传入参数,关于为啥不能更改我们上面的传入参数个数,我下面的代码块会有注释
注意:-------@express_flag("-"),先执行express_flag("-"),返回decorator,然后执行@decorator
#不能够像这样来更改函数make_p(func,parameter2)
#因为我们@decorator的过程是<=>函数名=decorator(函数名)
def express_flag(flag):
def decorator(func):
def inner(a,b):
if flag=="-":
print("我们正在执行减法函数")
elif flag=="+":
print("我们正在执行加法函数")
func(a,b)
return inner
return decorator
@express_flag("-")
def subtraction(num1,num2):
print("result=%d"%(num1-num2))
@express_flag("+")
def add(num1,num2):
print("result=%d"%(num1+num2))
add(2,4)
subtraction(1,3)
类装饰器
这是一个自定义的使用类来实现装饰功能的,这里我先提一下__call__方法
这个方法能够让类像函数一样调用
class A(object):
def __call__(self, *args, **kwargs):
print("使用调用")
A()()
#这样写不太规范 A()表示实例一个A的对象,然后去调用,
其实函数也是使用这个方法来实现调用,可以用dict函数看看
这里介绍这个内置方法是因为下面的代码执行@Decorate,的内部过程是
say=Decorate(say),这样不就把say变成一个对象了吗,后文会出现say()的调用方式,为了不报错,就得使用调用对象的方法
class Decorate(object):
def __init__(self,func):
self.__func=func
def __call__(self, name):
print("我能够多加上功能了")
self.__func(name)
@Decorate
def say(name):
print("我%s很饿的"%name)
say("小明")
如果看到这篇文章的小伙伴由什么问题,可以留言我们一起交流学习哟。bye!!!
因为最近发现以前学的python好多的忘记了,所以来复习一下,后面关于
内置的装饰器像基本的@staticmethod,@classmethod,@property我会后面在更新`>