装饰器基础

1.示例

import time
print(time.time())  #1559635927.77328...从
time.sleep(5)     #让程序在执行到此位置停n秒
print('aaa')

2.在这个基础上,我们写一个函数

def func():            #计算函数执行时间(合并)
    start=time.time()
    list1=[1,2,3,4,5]
    s=int(input("请输入一个值:"))
    list1.append(s)
    for i in list1:
        print(i,end='   ')
    print('
')
    end=time.time()
    print(end-start)

func()

3.分开

def time1(f):                 #将计算函数执行时间的函数独立出来
    startx=time.time()
    f()
    endx=time.time()
    print(endx-startx)

def func1():
    list1 = [1, 2, 3, 4, 5]
    s = int(input("请输入一个值:"))
    list1.append(s)
    for i in list1:
        print(i, end='   ')
    print('
')

time1(func1)


4.修饰

#用作对比
def
time1(f): #将计算函数执行时间的函数独立出来 startx=time.time() f() endx=time.time() print(endx-startx) def func1(): list1 = [1, 2, 3, 4, 5] s = int(input("请输入一个值:")) list1.append(s) for i in list1: print(i, end=' ') print(' ') time1(func1)

#希望使用func1(),不希望调用时使用time1()
#time2就是一个装饰器函数,只是对一个函数有一些装饰作用
#time2:装饰器函数 func2:被装饰的函数
def func2():
list1 = [1, 2, 3, 4, 5]
s = int(input("请输入一个值:"))
list1.append(s)
for i in list1:
print(i, end=' ')
print(' ')

def time2(f): #传入的实际上是func1函数的内存地址
def inner():
startx = time.time()
f()
endx = time.time()
print(endx - startx)
return inner #返回的都不用加括号,就那个名字已经是函数的地址

func2=time2(func2) #使用闭包
func2()

5.语法糖---@装饰器名---

def time2(f):              #传入的实际上是func1函数的内存地址
    def inner():
        startx = time.time()
        f()
        endx = time.time()
        print(endx - startx)
    return inner           #返回的都不用加括号,就那个名字已经是函数的地址
@time2                     #必须先定义time2(这里要紧贴被修饰的函数)作用相当于func2=time2(func2)
def func2():
    list1 = [1, 2, 3, 4, 5]
    s = int(input("请输入一个值:"))
    list1.append(s)
    for i in list1:
        print(i, end='   ')
    print('
')

func2()

6.如果被修饰的函数有返回值

def time2(f):     #传入的实际上是func1函数的内存地址
    def inner():
        startx = time.time()
        ret=f()
        endx = time.time()
        print(endx - startx)
        return ret
    return inner
@time2
def func2():
    list1 = [1, 2, 3, 4, 5]
    s = int(input("请输入一个值:"))
    list1.append(s)
    for i in list1:
        print(i, end='   ')
    print('
')
    return list1
#func2=time2(func2)  #使用闭包

ret=func2()
print(ret)

7.被装饰的函数带参数

#被装饰的函数有参数
import time
def time2(f):     #传入的实际上是func1函数的内存地址
    def inner(a):
        startx = time.time()
        ret=f(a)
        endx = time.time()
        print(endx - startx)
        return ret
    return inner
@time2
def func2(a):
    print(a)
    list1 = [1, 2, 3, 4, 5]
    s = int(input("请输入一个值:"))
    list1.append(s)
    for i in list1:
        print(i, end='   ')
    print('
')
    return list1
#func2=time2(func2)  #使用闭包

a='开始:'
ret=func2(a)
print(ret)

8.多个参数都被装饰,且传入的参数个数不一致

#多个被装饰的函数传入不同个参数
def time2(f):     #传入的实际上是func1函数的内存地址
    def inner(*args,**kwargs):      #完美的装饰器,万能参数都可以,加入后面有被修饰的函数
        startx = time.time()
        ret=f(*args)
        endx = time.time()
        print(endx - startx)
        return ret
    return inner
@time2
def func2(a):
   pass
@time2
def func3(a,b):
   pass
func2(1)
func3(2,b=4)   #只用*args是顶不住的,所以加*kwargs

9.总结

def wrapper(f):                  #装饰器的固定模式。
    def inner(*args,**kwargs):
        #在装饰之前要做的事
        ret=f(*args,**kwargs)
        #在装饰之前要做的事
        return ret
    return inner
#wrapper是装饰器的一般起名
#参数f是被装饰的函数
#定义一个新的内部函数,后面一定返回这个内部函数
@wrapper
def f():
pass

10.开放封闭原则

#开放封闭原则
#1.开发:对扩展是开放的
#2.封闭:对修改是封闭的(封版)
#函数重构一般不会轻易进行
#在已经写好的函数中,绝对不会再修改(除非已经到了一定要重构的地步)
#装饰器就可以不修改原来的函数,也修改了函数的功能
原文地址:https://www.cnblogs.com/lowislucifer/p/10974785.html