装饰器:
1.装饰器定义:在不改变函数的内容和调用的前提下,对函数进行功能扩展
2.装饰器本质就是闭包,通过闭包来实现
3.闭包实现功能扩展分析步骤
"""这是闭包实现功能扩展"""
#
# def task(func):
# def inner():
# print("我是扩展的功能---")
# func()
# return inner
#
# def f1():
# print("我是基础代码----")
#
# f1 = task(f1)
# f1()
"""闭包实现功能扩展分析步骤
1.函数从上到下执行,先定义task函数,再定义f1函数
2.执行f1=task(f1):先算等号右边,task(f1):调用task函数,把f1赋值给func,即func指向基础函数的代码块;等号左边:把执行完task(func)的返回再给f1重新赋值,f1指向了内部函数的代码空间
3.执行f1(),也就是调用内部的inner函数
"""
4.装饰器执行过程分析
def task(func):
def inner():
print("我是扩展的功能---")
func()
return inner
@task#这一句就相当于f1 = task(f1)
def f1():
print("我是基础代码----")
f1()
"""装饰器执行过程分析:
1.函数从上到下执行,先定义task函数
2.执行@task#这一句就相当于f1 = task(f1),这里尚未定义f1函数,即等待f1被装饰函数
3.定义f1()即被装饰函数
4.执行@task #这一句就相当于f1 = task(f1):先算等号右边,task(f1):调用task函数,把f1赋值给func
,即func指向基础函数的代码块;
等号左边:把执行完task(func)的返回再给f1重新赋值,f1指向了内部函数的代码空间
5.执行f1(),也就是调用内部的inner函数
"""
5.装饰器装饰不同类型的函数:
"""
装饰器装饰不同类型的函数
a>装饰器装饰的函数没有参数,没有返回值
b>装饰器装饰的函数有参数,没有返回值
c>装饰器装饰的函数没参数,有返回值
d>装饰器装饰的函数有参数,有返回值
"""
#a>装饰器装饰的函数没有参数,没有返回值
def w1(func):
def inner():
print("我是扩展的函数..")
func()
return inner
@w1
def f1():
print("我是基础函数....")
f1()
#b>装饰器装饰的函数有参数,没有返回值
def w1(func):
def inner(num):
print("我是扩展的函数..")
func(num)
return inner
@w1
def f1(num):
print("我是基础函数....",num)
f1(1)
#c>装饰器装饰的函数没参数,有返回值
def w1(func):
def inner():
print("我是扩展的函数..")
# result = func()
# return result
return func()#简化代码,跟上面两句一样
return inner
@w1
def f1():
print("我是基础函数....")
return "123456"
s = f1()
print(s)
#d>装饰器装饰的函数有参数,有返回值
def w1(func):
def inner(num):
print("我是扩展的函数..")
# result = func()
# return result
return func(num)#简化代码,跟上面两句一样
return inner
@w1
def f1(num):
print("我是基础函数....")
return num
s = f1(231)
print(s)
6.多个装饰器装饰一个函数的执行顺序:
"""
多个装饰器装饰一个函数的执行顺序:
1.装饰的顺序:由里到外,先装饰w2,再到w1
2.执行顺序:由外到里,从上到下依次执行
"""
def w1(func):
print( "我是w1")
def inner():
print("我是扩展的功能模块1")
func()
return inner
def w2(func):
print("我是w2")
def inner():
print("我是扩展的功能模块2")
func()
return inner
@w1
@w2
def f1():
print("我是被装饰的函数")
f1()
7.万能装饰器:
"""
1.装饰器定义:
在不改变函数的内容和调用的前提下,对函数进行功能扩展
2.万能装饰器
可以接收多个或着一个也不接收的 可以有返回值也可以没有返回值
"""
#万能装饰器
def w1(func):
def inner(*args,**kwargs):
print("我是扩展的功能")
return func(*args,**kwargs)
return inner
@w1
def f1(*args,**kwargs):
print("我是被装饰的函数...")
print(args)
print(kwargs)
return "11111"
s= f1(2)
print(s)
8.类装饰
"""
通过定义类的方式实现装饰器
装饰器定义: 在不改函数的内容和调用的前提下,对函数进行功能拓展
"""
class Foo(object):
def __init__(self,func):
self.func = func
def __call__(self, *args, **kwargs):
print("我是扩展的功能")
self.func()
@Foo#这一句等于pay=Foo(pay) pay指向的是实例对象
def pay():
print("我是被装饰的函数")
#这里的pay是实例对象,如果加了括号来调用,则需要在类中添加__call__魔法方法
#所以在这里将要扩展的功能放到这
pay()
9.带有参数的装饰器对函数进行装饰:
"""
带参数的装饰器对函数进行装饰
装饰器的定义:在不改变函数的内容和调用的前提下,对函数进行功能扩展
需求: 希望再装饰函数时额外传一个参数flag:
flag==1: 执行装饰的功能.执行身份验证
flag==0: 不执行装饰的功能,不执行身份验证
小结: 通过装饰器工厂实现对装饰器传递额外的参数
"""
def outer(flag):
def task(func):
def inner():
if flag == 1:
print("我是扩展的功能---")
func()
return inner
return task
# 这里在装饰器的外部再套了一个函数,同时也返回了task这个函数,
# 也就相当于@outer=@task,最终还是装饰器@task
@outer(0) # 表示手动调用函数 @outer(1)=@task
# @task pay=task(pay)
def f1():
print("我是基础代码----")
f1()
10.装饰器的总结:
1.装饰器函数只有一个参数,该参数就是被装饰的函数的引用
2.装饰器能够将一个函数的功能在不修改代码的情况下进行扩展
3.在函数定义的上方@装饰器的函数名 即可直接使用装饰器对下面的函数进行装饰
4.装饰器的应用场景;
1.引入日志
2.函数执行时间的统计
3.执行函数前预备处理
4.执行函数后的清理功能
5.权限校验等场景
6.缓存