python 装饰器

啥是装饰器?

  python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动(被装饰的函数调用方式 返回值等不改变)的前提下增加额外的功能,装饰器的返回值也是一个函数对象(函数的指针)

  装饰器作用 是对于我们已经写好的程序,可以抽离出一些雷同的代码组建多个特定功能的装饰器,这样我们就可以针对不同的需求去使用特定的装饰器,这时因为源码去除了大量泛化的内容而使得源码具有更加清晰的逻辑

装饰器的属性:

  实质: 是一个函数

  参数:是你要装饰的函数名(并非函数调用

  返回:是装饰完的函数名(也非函数调用

  作用:为已经存在的对象添加额外的功能

  特点:不需要对对象做任何的代码上的变动

  多个装饰器的执行顺序:是从近到远依次执行。

装饰器的应用场景:

  插入日志、性能测试、事务处理、权限校验、统计函数的执行时间等

 

在看装饰器之前,我们先来搞清楚什么是闭包函数:

  如果内部函数里引用了外部函数里定义的对象(甚至是外层之外,但不是全局变量),那么此时内部函数就被称为闭包函数。闭包函数所引用的外部定义的变量被叫做自由变量闭包从语法上看非常简单,但是却有强大的作用。闭包可以将其自己的代码和作用域以及外部函数的作用结合在一起

  总结:什么函数可以被称为闭包函数呢?主要是满足两点:函数内部定义的函数;引用了外部变量但非全局变量。

 

 

装饰器的代码案例

 

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

username, password = 'root', 'root123'

def autoLogin(loginType):
    print('loginType:', loginType)
    def outWrapp(func):
        def wrapp(*args, **kwargs):
            inName = input('username:')
            inPasswd = input('password:')
            if inName == username and inPasswd == password :
          print("login sucess")            
else:
          print("Invalid login username or password error")
return return func(*args, **kwargs) return wrapp return outWrapp @autoLogin(loginType='web') def webLogin(): print('in webLogin funtion'.center(50, '*')) return "webLogin function" @autoLogin(loginType='local') def localLogin(): print('in localLogin funciton'.center(50, '=')) return "localLogin function" webResult = webLogin() print(webResult) localResult = localLogin() print(localResult)

上面的案例 看似完美解决了在不改变原来函数代码的情况下新增了一些功能,也没有改变函数的调用方式。 但是函数的函数名属性却被我们改变了, 怎么看我们改变了函数的函数名属性呢,  我们可以打印一下函数的属性名就知道了 print(webLogin.__name__)  结果返回的不是 webLogin,而是wrapp。这是为什么呢? 其实函数名也是一个变量,而装饰器装饰函数其实是把原来的函数进行包装返回一个闭包函数给原来的变量名。就相当于 def func1(): pass      fun=func1 一样 fun.__name__ 返回的就是func1.  那这样不是也相对于改变被装饰的函数了嘛, 有没有一种方法可以解决这个问题呢? 当然有方法, 不然装饰器的特点就变成了缺点。方法就是应用一个包的函数:functools.wraps()

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from functools import wraps


def decoratorFun(func):
    @wraps(func) 
    def innerFunc():
        print('in inerFunc')
        return func()
    return innerFunc

@decoratorFun
def outfun():
    print('in outfun')

print(outfun.__name__)

#output: outfun

这样我的装饰器才算完美。

 

posted @ 2019-05-14 11:16  怡梦  阅读(133)  评论(0编辑  收藏  举报