python基础之装饰器
装饰器:本质就是函数,功能是为其他函数添加附加功能
原则:
1.不修改被修饰函数的源代码
2.不修改被修饰函数的调用方式
装饰器的知识储备:
装饰器=高阶函数+函数嵌套+闭包
高阶函数:
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数
以下代码实现了为函数foo增加一个新的功能,计算函数运行时间。函数接收的参数是一个函数名,所以是一个高阶函数,不过却改变了函数的调用方式,需要调用test(foo),所以不算一个装饰器
import time def foo(): time.sleep(3) print("我很好,谢谢你的关心") def test(func): print("你好吗") start_time = time.time() func() stop_time = time.time() print("函数运行的时间为 %s" % (stop_time-start_time)) test(foo)
接下来的代码满足高阶函数,也满足不改变函数的调用方式,不过多运行了一次,不符合要求
def foo(): time.sleep(3) print("我很好,谢谢关心") def test(func): print("你好吗") start_time = time.time() func() stop_time = time.time() print("函数的运行时间为 %s" % (stop_time-start_time)) return func foo = test(foo) foo()
加上函数嵌套,就可以达到装饰器的效果
def foo(): time.sleep(3) print("我很好,谢谢你的关心") def test(func): print("你好吗") def test1(): start_time = time.time() func() stop_time = time.time() print("函数运行的时间为 %s" % (stop_time-start_time)) return test1 foo = test(foo) foo()
不过也不是很完美,多了foo=test(foo)的调用,所以为了省去这步调用,对其他函数也可以,用如下代码
def test(func): print("你好吗") def test1(): start_time = time.time() func() stop_time = time.time() print("函数运行的时间为 %s" % (stop_time-start_time)) return test1 @test #相当于foo=test(foo) def foo(): time.sleep(3) print("我很好,谢谢你的关心") foo()
至此,一个简单的装饰器就完成了。
接下来可以替它美化功能。
美化1.如果函数里面带有参数,该怎么处理呢,毕竟每个函数的参数个数什么的都不确定。解决方法如下:注意看标红部分。
def test(func): print("你好吗") def test1(*args,**kwargs): start_time = time.time() func(*args,**kwargs) stop_time = time.time() print("函数运行的时间为 %s" % (stop_time-start_time)) return test1 @test def foo(name,age): time.sleep(3) print("我很好,谢谢你的关心") print("我是%s" % name) print("我今年%s岁" % age) foo('alex',18)
美化2:如果函数里面带有返回值又该如何处理呢。
def test(func): print("你好吗") def test1(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) stop_time = time.time() print("函数运行的时间为 %s" % (stop_time-start_time)) return res return test1 @test def foo(name,age): time.sleep(3) print("我很好,谢谢你的关心") print("我是%s" % name) print("我今年%s岁" % age) return age foo('alex',18)