# 首先介绍闭包(理解闭包是理解装饰器的前提)
# 什么是闭包呢?在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
def test01(num):
def test02():
print("num is %d" % num)
return test02
ret = test01(20)
ret()
print("*" * 60)
# 装饰器的理解
# 需求:在不更改源代码的情况下,对原来的方法添加一些验证。比如:flag==1 才执行 test01()等等
# 装饰器的应用场景:
# 1、引入日志
# 2、函数执行时间统计(这个可以常用啊)
# 3、执行函数前预备处理
# 4、执行函数后清理功能
# 5、权限校验等场景
# 6、缓存
# 无参数的装饰器
def test03(func):
print("-----1-----")
def test04():
print("-----2-----")
func()
return test04
# @test03 等价于下面这两句话
# test05 = test03(test05)
# test05()
@test03
def test05():
print("-----3-----")
test05()
print("*" * 60)
# 注意:装饰的函数是带参函数时,返回的test07()也必须是代参函数,用来接收
# 被装饰的函数有参数
def test06(func):
print("-----1-----")
def test07(name, age):
print("-----2-----")
func(name, age)
return test07
@test06
def test08(name, age):
print("-----3-----")
print("name is %s, %d" % (name, age))
test08("张三", 15)
print("*" * 60)
# 通用的装饰器函数,不论它是有参还是无参,有返回值还是无返回值,都是通用的
# args——存放元组参数,前面有一个*
# kwargs——存放字典参数,前面有两个*
# 补充:元组和字典的拆包:如果希望将一个元组或者字典直接传给函数,可在参数名前面加一个*或者两个*
def test09(func):
print("-----1-----")
def test10(*args, **kwargs):
print("-----2-----")
ret = func(*args, **kwargs)
return ret
return test10
@test09
def test11(*args, **kwargs):
print("-----3-----")
return args, kwargs
print(test11(*("腾讯", "阿里巴巴", "谷歌"), **{"张三": 15, "李四": 16, "王五": 17}))
print("*" * 60)
# 两个装饰器,首先看到第一个@test12,但是呢?发现下面还有一个@test14,而装饰器是用来装饰函数的,不能用来装饰@test14
# 所以要等下面的@test14装饰完了之后,@test12才能再装饰
# 两个装饰器(理解)
def test12(func):
print("-----1-----")
def test13():
print("-----2-----")
return "hello " + func()
return test13
def test14(func):
print("-----3-----")
def test15():
print("-----4-----")
return "python " + func()
return test15
@test12
@test14
def test16():
print("-----5-----")
return "world"
print(test16())
print("*" * 60)
# 1、因为装饰器带了参数,首先是直接调用timefun_arg(),返回了timefun,此时的@timefun_arg("itcast")就变成了@timefun
# 2、然后才装饰foo()函数
# 3、后面的步骤如上
def test17(str="hello"):
def test18(func):
def test19():
print("%s" % str)
return func()
return test19
print(str)
return test18
@test17("hello world")
def test20():
print("this is python world")
test20()
print("*" * 60)
# 类装饰器(了解)
# 要想理解类装饰器,首先需要理解下面这段代码
class test21(object):
def __call__(self):
print('call me!')
t = test21()
t()
# t是一个对象,又不是一个方法,怎么可以t()呢?
# 原来t()会默认调用__call__(self)方法,因为类test21重写了__call__(self)方法,所以调用重写后的
print("*" * 60)
# 接下来才是类装饰器(不得不说动态语言真是花里胡哨)
class test22(object):
def __init__(self, func):
print("---初始化---")
print("func name is %s" % func.__name__)
self.__func = func
def __call__(self):
print("---装饰器中的功能---")
self.__func()
@test22
def test():
print("----test---")
test()