学习 Alex python 自动化运维开发 装饰器
装饰器:
定义: 装饰器本质是函数,功能是装饰其它函数,为其它函数添加附加功能。
原则:
- 不能修改被装饰的函数源码
- 不能修改被装饰函数的调用方式
# -*- coding : utf-8 -*-
# @Data : 2020-02-07
# @Author : Ming Xu
# @Email : 920972751@qq.com
# @File : decorator.py
# Desctiption: 使用装饰器来统计 test 这个函数的运行时间
import time
def timmer(func):
def warpper(*args, **kwargs):
start_time = time.time()
func()
stop_time = time.time()
print("the func run time is %s" % (stop_time - start_time))
return warpper
@timmer
def test():
time.sleep(3)
print("this is test")
return 0
test()
装饰器的基础知识
高阶函数 + 嵌套函数 -----> 装饰器
- 函数即变量
- 高阶函数
把一个函数名当做实参传给另外一个函数
返回值中包含函数名
# -*- coding : utf-8 -*-
# @Data : 2020-02-07
# @Author : Ming Xu
# @Email : 920972751@qq.com
# @File : decorator_1.py
# Desctiption: 不是装饰器。只是功能类似
"""
把一个函数名当做实参传给另外一个函数
返回值中包含函数名
"""
import time
def bar(): # 定义了bar 这个函数
time.sleep(3)
print("in the bar")
def test(func): # bar作为实参传进来, 这个 其实这个时候func就等于bar 这个函数了
start_time = time.time()
func() # 运行 func这个变量(函数),, 其实就运行了bar这个函数
stop_time = time.time()
print("the func run time is %s" % (stop_time - start_time))
test(bar)
说明:
虽然我们没有改变bar函数 。 但实际改变了调用 bar 的方式(将bar作为实参使用了)
违背了第 2 条原则。 所以以上并不是装饰器。
高阶函数,返回值中包含函数名
# -*- coding : utf-8 -*-
# @Data :
# @Author : Ming Xu
# @Email : 920972751@qq.com
# @File :
# Desctiption:
import time
def bar():
print("in the bar")
def test(func):
start_time = time.time()
func()
stop_time = time.time()
print("the func run time is %s" % (stop_time - start_time))
return func # 进行这个变量(函数)作为返回值 ,这样这个函数的执行结果就是这个函数的内存地址(这个函数的变量名),就可以定义在外面定义变量了。
bar = test(bar) # 这样再定义bar,就可以不修改 bar这个源代码的调用方式了。
bar()
返回值中包含函数名的作用相当于不修改函数的调用方式
高阶函数的定义,在装饰器中可以理解为
- 把一个函数名当做实参传给另一个函数(不修改被装饰函数的情况下不修改源代码 )
- 返回值中包含函数名(不修改函数的调用方式 )
嵌套函数: 就是在函数里面再定义一个函数
def foo():
print("in the foo")
def bar (): #这里定义的bar函数,一定要在foo里面才能调用, 作用类似于局部变量,bar这个函数在全局是不生效的。
print ("in the bar")
bar()
foo()
然后将高阶函数和嵌套函数结合起来使用
# -*- coding : utf-8 -*-
# @Data :
# @Author : Ming Xu
# @Email : 920972751@qq.com
# @File :
# Desctiption: 高阶函数和嵌套函数一起使用
import time
def timer(func): # 高阶函数: 把函数作为实参进来
def deco(): # 嵌套函数:函数里面定义函数
start_time = time.time()
func()
stop_time = time.time()
print("the func run time is %s" % (stop_time - start_time))
return deco # 高阶函数:用函数作为返回值。 这边定义的返回值其实是deco这个函数, 在timer这个函数里面无需执行
def test1():
time.sleep(3)
print("in the test1")
test1 = timer(test1) # 外部调用函数
test1()
在 python3 中可以直接使用 @ 符号来调用装饰器,它一定要写在被修饰函数的前面
# -*- coding : utf-8 -*-
# @Data :
# @Author : Ming Xu
# @Email : 920972751@qq.com
# @File :
# Desctiption: @ 装饰函数
import time
def timer(func):
def deco():
start_time = time.time()
func()
stop_time = time.time()
print("the func run time is %s" % (stop_time - start_time))
return deco
@timer # 直接@符加修饰器名字。 但是一定要写在被修饰函数的前面 @time ==== test1=timer(test1)
def test1():
time.sleep(3)
print("in the test1")
装饰器传参
import time
def timer(func):
def deco(*args,**kwargs): ### 进行传参
start_time=time.time()
func(*args,**kwargs) ### 因为这个func函数在这边是直接调用的,不是定义的。所以参数需要deco传进来
stop_time=time.time()
print ("the func run time is %s" %(stop_time-start_time))
return deco
@timer # test2 = timer(test2) ==> 其实 test2()== fun() 执行是 deco(),所以test2()传参就是 deco() 传参 再传给func()
def test2(name,age):
time.sleep(1)
print ("this is %s,%s" %(name,age) )
test2("Alex", 22)