专栏文章 开篇测试 - 学习 python 装饰器用法

我去催饭 · 2021年11月24日 · 最后由 底层贫困人员 回复于 2021年11月24日 · 2524 次阅读

不懂装饰器,好意思说会 python 吗

装饰器,语法糖,多态,闭包,面向对象……这是我无数次翻阅《python 核心编程》,无数次从入门到放弃的重蹈覆辙,是我一直迈不过去的坎儿。就犹如英语里的 one car come,one car go,two car pengpeng,people die!日语里的この番組は、ご覧のサバンナの提供して送りします一样,连个装饰器都学不明白,好意思说自己会 python?痛定思痛,这一次,就让我借助测试开发干货群里的两位大佬的分享,好好地再学习一下装饰器这个神秘的@func组成的神奇工具吧。

首先是测试开发杂货汤总的文章(https://mp.weixin.qq.com/s/ezOnoSCO4OO-6xlWW_PQ0g),最近更新的。这一次,我决定抛弃 * 点赞收藏转发一健三连≈我学会了 * 的觉悟,认认真真地学习一下。

忘记键盘上的 ctrl c v 吧,老老实实照着敲一遍,连注释都要手工复制下来:

#coding=utf8
import time
import urllib3,requests
from functools import wraps

def get_time(api):
    '''
    获取时间功能
    '''
    print("现在运行get_time(api)")
    @wraps(api)
    def get():
        print("现在运行get()")
        start = time.time()
        api()
        stop = time.time()
        print("函数运行时间为:",stop - start)
    return get

@get_time
def get_api():
    """
    获取信息接口
    """
    print("现在运行get_api()")
    url = "https://easy-mock.home.qyzhg.com:10443/mock/61922bfd6e616600201c7c3e/test/getapi"
    json = {}
    urllib3.disable_warnings()
    time.sleep(3)
    result = requests.post(url, json=json, verify=False).json()
    print(result)

if __name__ == '__main__':
    get_api()
    # 打印函数里注释的内容
    print(get_time.__doc__)
    # 打印get_time这个函数的函数名
    print(get_time.__name__)
    # 打印get_api这个函数里的注释内容
    print(get_api.__doc__)

值得注意的是上面引入的那些包,比如这个 wraps,我当时就不知道这个函数是哪里来的,一个大红线摆着很奇怪,然后看文章介绍是从 funtools 里引入的,遂加载之。正常调用,运行结果是这样的:

现在运行get_time(api)
现在运行get()
现在运行get_api()
{'data': {'message': 'success', 'status': 200, 'cctest': 'intelligent'}}
    函数运行时间为: 3.1157751083374023
    获取时间功能
    get_time
    获取信息接口

鲁迅说,要抱有怀疑态度,不能人云亦云。这个@wraps起什么作用我一定要弄清楚。


汤总说,如果不带这个@wraps,下面那个 get_api.doc会打印出一个 None,我就不信,我就要 44,44944,果断注释掉这个 wraps,什么错都没报,说明函数还是执行了的,不过结果不出意外:

执行get_time
执行get()
执行get_api()
{'data': {'message': 'success', 'status': 200, 'cctest': 'intelligent'}}
函数运行时间为: 3.1110358238220215
获取时间功能    
get_time
None

None 了!它 None 了!真是不听汤总言,吃亏在眼前啊。为啥呢,汤总都写清楚了:

如果没有这个@wraps,获取被装饰函数的信息,会显示 None,所以这个的作用就是:因为当使用装饰器装饰一个函数时,函数本身就已经是一个新的函数;即函数名称或属性产生了变化。所以在 python 的 functools 模块中提供了 wraps 装饰函数来确保原函数在使用装饰器时不改变自身的函数名及应有属性。

正所谓一看就会,一学就废,还是实践出真知啊!通过今天的学习,我再一次重温了 python 函数装饰器的作用,以及他们的作用顺序:执行装饰器” 最外层的 “的函数->执行” 装饰器里的装饰器 “函数->执行被调用函数本身。这只是我的第 N 次从入门到放弃的,算是比较明白的一回了。接下来要学习的是来自卷魔之王无敌哥关于装饰器的文章,兴奋地搓搓小手,继续学习吧~

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
最佳回复

沙发自己坐

共收到 6 条回复 时间 点赞

沙发自己坐

榜一大哥,无所畏惧

米洛 回复

阿偶。。不能控评

榜一大哥,完爆我和无敌哥

来得早,还能伪前排

榜一大哥,无所畏惧

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册