博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python迭代器、生成器、装饰器之装饰器
阅读量:5302 次
发布时间:2019-06-14

本文共 2551 字,大约阅读时间需要 8 分钟。

装饰器。。。。。。

定义:本质是函数,为其他函数添加附加功能

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

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

仔细观察下面代码,看看有什么发现。

内嵌函数+高阶函数+闭包=》装饰器

import time# 内嵌函数def timmer(func):    def wrapper(*args, **kwargs):        start_time = time.time()        res = func(*args, **kwargs)        stop_time = time.time()        print('run time is %s' % (stop_time - start_time))        return res    return wrapper  # 返回函数名@timmerdef foo():    time.sleep(3)    print('from foo')foo()

高阶函数。。。。。下面的例子中foo就是属于一个高阶函数。

'''高阶函数:    1、函数接收的参数是一个函数名    2、函数的返回值是一个函数名    只要满足其中一个就属于高阶函数'''def fun():    print("from fun")def foo(fun1):    fun1()foo(fun)

 返回值是函数名的高阶函数

def fun():    print("from fun")def foo(fun1):    return fun1foo(fun)()

函数嵌套。。。。。。通过下面的例子,可以看出,函数内可以套函数,而函数也是一个变量,

通过locals()可以看到。

'''函数嵌套'''def fun1():    print("from fun1")    def fun2():        print("from fun2")    print(locals())fun1()# 运行结果#from fun1#{'fun2': 
.fun2 at 0x000002A2C4D4AD90>}

闭包闭包,一个函数一个包。。。主要还是作用域,请看

 

重点来了。装饰器。。。。。。

# 简单的装饰器例子def timer(func):    def wrapper():        func()    return wrapperdef test():    time.sleep(3)    print("test函数执行完毕")res = timer(test)res()

这是不对的,前面说过,装饰器不能修改被装饰函数的源代码,不能修改被装饰函数的调用方式。

这里调用时,修改了调用的方式。。。

那这样呢?

test = timer(test)test()

看着是没有修改调用方式,但是每次调用时都会重新赋值。。。这样不合理

那应该怎么做?下面这样写,仅仅是在函数调用之前加上@装饰器名字即可

@timertest()

看下面的例子,看看都打印了什么。

def timer(func):    def wrapper():        func()    return wrapper@timerdef test():    time.sleep(2)    print("test函数执行完毕")    return "test()的返回结果"res = test()print(res)

可以发现,我们并没有得到test()函数的返回值,如果想要得到被装饰函数的返回值,需要这样写

def timer(func):    def wrapper():        res = func()        return res    return wrapper

在装饰器中通过变量来接收被装饰函数的返回值,然后利用return返回。这样一个带有返回值的装饰器就书写完成了。

这些还远远不够,有时候我们被修饰的函数还需要传入一些参数

def timer(func):    def wrapper(name, age):        res = func(name, age)        return res    return wrapper@timerdef test(name, age):    time.sleep(2)    print("name:%s,age:%d," % (name, age))    print("test函数执行完毕")    return "test()的返回结果"res = test('june', 18)print(res)

上面的例子虽然可以传递参数,但依然存在不足,当test()的参数变化时,上面的例子就不能用了,需要对装饰器进行改进

def timer(func):    def wrapper(*args, **kwargs):        res = func(*args, **kwargs)        return res    return wrapper

上面的这个例子可以实现无论被修饰函数的参数如何让改变,都能够接收。关于*args,**kwargs可以参考

好了,目前为止我们写的装饰器可以传入参数,也可以拥有返回值了,那么如果我们的装饰器还需要参数的话,那。。。。

def auth(filed):    print(filed)    def fun1(fun):        def fun2(*args, **kwargs):            fun(*args, **kwargs)        return fun2    return fun1@auth("我是装饰器的参数")def foo():    print("from foo")foo()

在原来的基础上再加一层函数。。。

小结,不修改原函数代码,不修改原函数的调用方式。

转载于:https://www.cnblogs.com/June-King/p/10596205.html

你可能感兴趣的文章
as3.0 [Embed]标签嵌入外部资源
查看>>
Python 发 邮件
查看>>
mysql忘记密码的解决办法
查看>>
全面分析Java的垃圾回收机制2
查看>>
[Code Festival 2017 qual A] C: Palindromic Matrix
查看>>
[Python设计模式] 第11章 迪米特法则——最少知识原则
查看>>
社交网站怎么利用好等级制度
查看>>
修改博客园css样式
查看>>
Django之锁,事物,Ajax
查看>>
Redis的学习笔记
查看>>
PMP备考
查看>>
Python3 高阶函数
查看>>
c语言入门-02-第一个c程序开始
查看>>
iOS常用宏定义--实用
查看>>
关于gitlab搭建方法的几点补充
查看>>
初始面向对象
查看>>
<松本行弘的程序世界> 读书笔记
查看>>
docker一键安装
查看>>
leetcode Letter Combinations of a Phone Number
查看>>
kbhit()
查看>>