码迷,mamicode.com
首页 > 编程语言 > 详细

Python装饰器

时间:2018-10-09 11:43:27      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:知识   语法糖   需要   代码   使用   就是   span   需求   函数名   

现有如下函数:

def fun1():
    print(‘...fun1()...‘)

def fun2():
    print(‘...fun2()...‘)

#调用函数
fun1()
fun2()

 

需求:需要给以上两个函数添加记录日志功能

方法一:函数调用

def logging():
    print(‘...logging...‘)

def fun1():
    print(‘...fun1()...‘)
    logging()

def fun2():
    print(‘...fun2()...‘)
    logging()

#调用函数
fun1()
fun2()

 分析:上面这种方式适合少量函数调用,如果有n个地方需要调用logging()函数,那么得手动调用n次,比较麻烦,而且在fun1()中调用loggin()也相当于修改了fun1()的内容。

 

方法二:高阶函数(函数名作为参数传递给另一个函数)

def logging(fun):
    fun()
    print(‘...logging...‘)

def fun1():
    print(‘...fun1()...‘)


def fun2():
    print(‘...fun2()...‘)


#调用函数
logging(fun1)
logging(fun2)

 分析:该方法是高阶函数的用法,将函数名当做参数传递给另一个函数,优点是没有修改源代码,缺点是该方法修改了调用的方式。

 

方法三:高阶函数(返回值中包含函数名)

def logging(fun):
    print(‘...logging...‘)
    return fun


def fun1():
    print(‘...fun1()...‘)


def fun2():
    print(‘...fun2()...‘)


#调用函数
fun1 = logging(fun1)
fun2 = logging(fun2)
fun1()
fun2()

 该方法的优点是没有改变原有函数的调用方式,但是改变的原有输出顺序。

 

方法四:嵌套函数

def logging(fun):
    def dec(fun):
        return fun()
    dec(fun)
    print(‘...logging...‘)


def fun1():
    print(‘...fun1()...‘)


def fun2():
    print(‘...fun2()...‘)


#调用函数
logging(fun1)
logging(fun2)

 该方法优点是没有修改源代码,但是调用方式改变了。

 

总结:

如果需要不修改源代码、不修改调用方式,则需要使用高阶函数+嵌套函数一起,由此引入了装饰器的概念。

 

 

装饰器

定义:本质是函数(装饰其他函数),就是为其他函数添加附加功能。

原则:1.不能修改被装饰函数的源代码

   2.不能修改被装饰函数的调用方式

 

装饰器知识储备:

1.函数即“变量”
2.高阶函数
a:函数名作为实参传给另一个函数(在不修改源代码的情况下为其新增功能)
b:返回值中包含函数名(不修改函数的调用方式)
3.嵌套函数
高阶函数+嵌套函数=>装饰器

 

使用高阶函数+嵌套函数修改上面需求:

def logging(fun):
    def dec():
        fun()
        print(‘...logging...‘)
    return dec


def fun1():
    print(‘...fun1()...‘)


def fun2():
    print(‘...fun2()...‘)


#调用函数
fun1 = logging(fun1)
fun2 = logging(fun2)
fun1()
fun2()

 

装饰器语法糖:即在函数前使用@函数名

使用语法糖修改以上代码:

def logging(fun):
    def dec():
        fun()
        print(‘...logging...‘)
    return dec

@logging
def fun1():
    print(‘...fun1()...‘)

@logging
def fun2():
    print(‘...fun2()...‘)


#调用函数
fun1()
fun2()

如上案例中的@logging可以理解为:fun1 = logging(fun1)

 

Python装饰器

标签:知识   语法糖   需要   代码   使用   就是   span   需求   函数名   

原文地址:https://www.cnblogs.com/jmwm/p/9759251.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!