您的位置:首页 > 编程语言 > Python开发

python 装饰器详解

2018-01-21 14:26 519 查看
引入装饰器的思想:

如果我们想为某一个功能添加一个新的功能,如何在不改变他的原来的函数名的情况下实现呢?

我们可能会这样:

1.直接在原来的函数里头添加功能模块 --- 代码量太大逐一添加不太现实

2.再写一个新的函数,在原来的函数里分别调用 --- 如果原来的函数在多处调用,且太过分散,工程量太大

3.定义一个新的函数:
def cover():
   newFunc()
   oldFunc()

  在新函数里头注入一个参数为 -- 原来的函数(函数作为参数传入)
def cover(oldFunc)  -- 此处不能有括号否则为调用函数
   newFunc()
   oldFunc()
cover(oldFunc)  -- 调用

那么这样又违背了题意 --- 显然不合格

上述的三种方法都不能实现,那么装饰器的思想应运而生

即在第三种方法的理念下,既添加了新功能,有没有修改名字
def covered(func):
   def cover():
newFunc()
oldFunc()
   return cover
即: cover = covered(oldFunc)
   cover()  ">="  oldFunc()
   调用oldFunc 就可以写作调用cover()
   cover()函数是oldFunc()函数的增强版

   实现换皮不换肉,还变肥的操作

我们重新归纳:

def newFunc():

    print("需要添加的新功能")

def outter(fun):

    def inner(name):

        newFunc()

        return fun(name)

    return  inner

# 在一个函数上加上@,表示使用装饰器,@符号后跟的是 装饰器的函数名

# 如: @outter  相当于执行了  func = outter(func)  --->   将inner修改成原函数名 = 装饰器函数名(需要添加新功能的原函数名)

@outter

def func(name):

    print("%s的基础功能"%name)

    return name

print(func("胖胖"))  #inner("胖胖") 注意此处的func与原来的并不是一样的,而是改装后名字一样而已

这就是装饰器的基本思想,那么如何实现一个通用的装饰器呢?即实现一个通用的装饰器,起始也很简单只需要在传参上修改就行:

def newFunc():
print("需要添加的新功能")

def outter(fun):
def inner(*args,**kwargs):
newFunc() # 如果有必要,可以在新功能出也添加
return fun(*args,**kwargs)
return inner

@outter
def func(name,food):
print("%s的基础功能是吃%s"%(name,food))
return name
print(func("小贱贱","面包")) #<==> print(inner("小贱贱","面包"))我们来看看具体应用:

一.创建一个装饰器把下面函数输出的字符串首字母大写

# 思路: 使用装饰器,装饰器可以给原函数重新命名,添加新的功能

#       可以在装饰器里给新旧函数排序使得旧函数有新的功能

# def geeting(word="hi there"):

#    return word.lower()
#解答:
def newGeeting(word):
return word.capitalize()

def change(geet):
def geetings(**kwargs):
geet(**kwargs)
return newGeeting(**kwargs)
return geetings
@change
def geeting(word="hi there"):
return word.lower()
print(geeting(word="hi there"))
二.使用一个装饰器,查看函数运行时间

# 思路:运行时间 导入时间模块,在装饰器内部 函数前后分别获取当前时间戳,函数运行结束后,差值就是函数运行时间
#解答:
import time

def time1(func):
def newFunc():
startTime = time.time()
func()
endTime = time.time()
return endTime-startTime
return newFunc

@time1
def oldFunc():
time.sleep(2)
print("我正在运行中")
print(oldFunc())

那么装饰器就说到这里,你是否有所收获呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python