返回顶部
首页 > 资讯 > 后端开发 > Python >Python装饰器函数怎么使用
  • 672
分享到

Python装饰器函数怎么使用

2023-07-02 13:07:20 672人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章主要介绍了python装饰器函数怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python装饰器函数怎么使用文章都会有所收获,下面我们一起来看看吧。假如我写了一个函数 fdef f()

这篇文章主要介绍了python装饰器函数怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python装饰器函数怎么使用文章都会有所收获,下面我们一起来看看吧。

Python装饰器函数怎么使用

假如我写了一个函数 f

def f():    print('hello')

之后我想知道这段函数执行所要的时间,这好办,我只要将代码改为如下就行

import timedef f():    start = time.time()   #获取程序执行开始的时间    print('hello')    end = time.time()     #获取程序执行结束的时间    print(end - start)    #得出函数f执行所要时间f()

但之后我有写了无数个函数f2,f3……fn,我想知道每个函数执行所需要的时间,那么如果都像上面一样改,岂不是很闹心?还是不行,因为这样实在是太麻烦了。那怎么办呢?于是灵机一动,写了一个timer函数。。。

import timedef timer(func):    start = time.time()    func()    print(time.time() - start)def f():    print('hello')def f2():    print('xorld')timer(f)timer(f2)

这样看起来是不是简单多啦?不管我们写了多少个函数都可以调用这个计时函数来计算函数的执行时间

但是如果我只想用原来的方式f1(),f2(),fn()调用了这个函数,函数在原本执行输出的结果不变的前提下还可以增加计算时间的功能,而不是调用timer(f),timer(f2)才能计算时间,这该怎么办呢?

看了下面的装饰器函数你就会知道如何解决这个问题



一、装饰器 —— 形成过程

以下就是解决上面问题的代码的简单版:

import timedef f():    print('hello')def timer(func):    def inner():        start = time.time()        func()        print(time.time() - start)    return innerf = timer(f)f()

还是这句话我只想用原来的方式f1(),f2(),fn()调用了这个函数,函数在原本执行输出的结果不变的前提下还可以增加计算时间的功能,但我还是要在函数 f 执行前写 f = timer(f)在这一串代码,是不是觉得碍眼?python的开发者也觉得碍眼,所以python的开发者就为我们提供了一句语法糖来解决这个问题!



二、装饰器 —— 初识语法糖

用@timmer代替f = timer(f),这就是一句语法糖。

import timedef timer(func):    def inner():        start = time.time()        func()        print(time.time() - start)    return inner@timer   #==> 写着这句话就相当于执行了f = timer(f)def f():    print('hello')f()


三、装饰器 ——本质与功能

本质

  装饰器的本质就是一个闭包函数

功能

在不修改原函数及其调用方式的情况下对原函数功能进行扩展

四、装饰器 —— 装饰带参数,返回值的装饰器

  • 1、装饰带一个参数的函数

刚才我们写的装饰器都是装饰不带参数的函数,现在要装饰一个带参数的函数怎么办呢?

import timedef timer(func):    def inner(a):        start = time.time()        func(a)        print(time.time() - start)    return inner@timerdef f(a):    print(a)f('hello')
  • 2、装饰多个带有不同参数但无返回值的函数

其实装饰带参的函数并不是什么难事,但假如你有两个函数,需要传递的参数不一样呢,比如  函数func1有两个参数func1(a ,b),函数func 2只有一个参数func2(a), 且它们都想用这个装饰器装饰,做到计算函数执行时间?这怎么办呢?那就用下面代码。

import timedef timer(func):    def inner(*args,**kwargs):        start = time.time()        re = func(*args,**kwargs)        print(time.time() - start)        return re    return inner@timer   #==> func1 = timer(func1)def func1(a,b):    print('in func1')@timer   #==> func2 = timer(func2)def func2(a):    print('in func2 and get a:%s'%(a))    return 'fun2 over'func1('aaaaaa','bbbbbb')print(func2('aaaaaa'))输出结果:in func10.0in func2 and get a:aaaaaa0.0fun2 over
  • 3、装饰多个带有不同参数且有返回值的函数

现在参数的问题已经完美的解决了,可是如果你的函数是有返回值的呢?用上面的代码你就拿不到返回值了那究竟要如何解决这个问题呢?那就看下面的代码吧!

import timedef timer(func):    def inner(*args,**kwargs):        start = time.time()        re = func(*args,**kwargs)        print(time.time() - start)        return re    return inner@timer   #==> func2 = timer(func2)def func2(a):    print('in func2 and get a:%s'%(a))    return 'fun2 over'func2('aaaaaa')print(func2('aaaaaa'))输出结果:in func2 and get a:aaaaaa0.0in func2 and get a:aaaaaa0.0fun2 over
  • 4、多个装饰器装饰同一个函数

有些时候,我们也会用到多个装饰器装饰同一个函数的情况。

ef wrapper1(func):   #func ----- f    def inner1():        print('wrapper1 ,before func')        func()        print('wrapper1 ,after func')    return inner1def wrapper2(func):    def inner2():        print('wrapper2 ,before func')        func()        print('wrapper2 ,after func')    return inner2@wrapper2       #f = wrapper2(f) ----->> wrapper2(inner1)  == inner2@wrapper1       #f = wrapper1(f) = innerdef f():    print('in f')f()    #===>>inner2#多个装饰器装饰同一个函数输出结果:wrapper2 ,before funcwrapper1 ,before funcin fwrapper1 ,after funcwrapper2 ,after func


五、装饰器 ——  装饰器进阶与优化

  • 1、带参数的装饰器

上面那个装饰器已经非常beautiful了,但是还有一个问题,如果我给代码中无数个函数都加了@timer这个语法糖,如果之后我又不想用它了那岂不是又要每个去将它注释,没日没夜忙活3天?岂不是特别麻烦,为了使装饰器不用时能够更好的回收而不是一个一个去注释或者删除 我们引入带参数的装饰器概念

'''为了使装饰器不用时能够更好的回收而不是一个一个去注释或者删除我们引入带参数的装饰器概念'''import time'''FLAGE的目的是用它控制装饰器的开关,那么当我们不用的时候就不要一个一个去注释只需将True改为False就行'''FLAGE = Truedef timmer_out(flag):    def timmer(func):        def inner(*args,**kwargs):            if flag:                start = time.time()                ret = func(*args,**kwargs)                end = time.time()                print(end - start)                return ret            else:                ret = func(*args, **kwargs)                return ret        return inner    return timmer@timmer_out(FLAGE)#timmer_out(FLAGE)# 也相当于执行  timmer_out(FLAGE)--->>返回timmer———————>>@timmer(wahaha = timmer(wahaha))def wahaha():    time.sleep(0.1)         #不休息的话函数执行的太快难以计算时间    print('wahahahahahaha')wahaha()@timmer_out(FLAGE)def erguotou():    time.sleep(0.1)         #不休息的话函数执行的太快难以计算时间    print('erguotoutoutou')erguotou()输出结果:wahahahahahaha0.10152268409729004erguotoutoutou0.10795140266418457
  • 2、防止函数必要信息失效

'''print(wahaha.__name__)      #查看字符串格式的函数名print(wahaha.__doc__)       #查看一个函数的注释'''#下面用__name__查看holiday的函数名from functools import wrapsdef wrapper(func):    @wraps(func)            #加在最内层函数正上方    def inner(*args,**kwargs):        print('在被装饰的函数执行之前做的事')        ret = func(*args,**kwargs)        print('在被装饰的函数执行之后做的事')        return ret    return inner@wrapper        #holiday = wrapper(holiday)def holiday(day):    '''    这是一个放假通知    :param day:    :return:    '''    print('全体放假%s天'%day)    return '好开心'print(holiday.__name__)print(holiday.__doc__)'''结果是inner和None 但我们想要的是打印holiday的字符串格式的函数名和函数的注释这时该怎么办?解决方法就是  from functools import wraps使用语法是@wraps(被装饰的函数名)'''输出结果:holiday    这是一个放假通知    :param day:    :return:


六、装饰器 —— 装饰原则

  • 开放封闭原则

对原函数的功能扩展是开放的

为什么要对功能扩展开放呢?

    对于任何一个程序来说,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许后来扩展、添加新功能。

对修改是封闭的

 为什么要对修改封闭呢?

就像我们刚刚提到的,因为我们写的一个函数,很有可能在其他地方已经被导入使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经正在使用该函数的代码。

装饰器就完美遵循了这个开放封闭原则。这就是学装饰器的初衷



小结:

  • 装饰器的固定格式(模板)

#格式一def timer(func):    def inner(*args,**kwargs):        '''执行函数之前要做的'''        re = func(*args,**kwargs)        '''执行函数之后要做的'''        return re    return inner#格式二from functools import wrapsdef deco(func):    @wraps(func) #加在最内层函数正上方    def wrapper(*args,**kwargs):        return func(*args,**kwargs)    return wrapper

关于“Python装饰器函数怎么使用”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Python装饰器函数怎么使用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网Python频道。

--结束END--

本文标题: Python装饰器函数怎么使用

本文链接: https://lsjlt.com/news/341898.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python中怎么使用装饰器装饰函数
    这篇文章将为大家详细讲解有关Python中怎么使用装饰器装饰函数,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。***个函数deco是装饰函数,它的参数就是被装饰的函数对象。我们可以在deco...
    99+
    2023-06-17
  • Python中怎么使用装饰器来装饰函数
    在Python中,装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数。通过使用装饰器,可以在不修改原始函数代码的情况下添加...
    99+
    2024-03-12
    Python
  • Python装饰器函数怎么使用
    这篇文章主要介绍了Python装饰器函数怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python装饰器函数怎么使用文章都会有所收获,下面我们一起来看看吧。假如我写了一个函数 fdef f()...
    99+
    2023-07-02
  • Python 函数装饰器怎么用
    这篇文章主要介绍Python 函数装饰器怎么用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、什么是函数装饰器函数装饰器是Python提供的一种增强函数功能的标记函数;装饰器是可调用的函数对象,其参数是另...
    99+
    2023-06-21
  • 怎么在python中使用函数装饰器
    怎么在python中使用函数装饰器?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研...
    99+
    2023-06-14
  • Python返回函数、闭包、装饰器、偏函数怎么使用
    今天小编给大家分享一下Python返回函数、闭包、装饰器、偏函数怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.返...
    99+
    2023-07-02
  • Python函数装饰器的使用教程
    目录典型的函数装饰器叠放装饰器参数化装饰器标准库中的装饰器functools.wrapsfunctools.lru_cachefunctools.singledispatch小结参考资料:典型的函数装饰器 以下示例...
    99+
    2022-06-02
    python 装饰器 python 函数装饰器
  • Python函数装饰器的使用详解
    目录装饰器装饰器的定义装饰器的意义装饰器的使用无参装饰器有参装饰器实例练习总结装饰器 装饰器的定义 关于装饰器的定义,我们先来看一段github上大佬的定义: Function de...
    99+
    2024-04-02
  • python装饰器1:函数装饰器详解
    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函数 方法 类 基础...
    99+
    2023-01-30
    详解 函数 python
  • Python装饰器-闭包与函数装饰器
    一、闭包在学习装饰器前,需要先了解闭包的概念。形成闭包的要点:函数嵌套将内部函数作为外部函数的返回值内部函数必须要使用到外部函数的变量下面以一个计算列表平均值的案例来讲解闭包:def make_average(): # 创建一个列表,用来保...
    99+
    2023-05-14
    Python 函数 装饰器
  • Python函数的装饰器
    函数的装饰器. 1. 装饰器   开闭原则:         对功能的扩展开放         对代码的修改是封闭     通用装饰器语法: def wrapper(fn): def inner(*args, **kw...
    99+
    2023-01-30
    函数 Python
  • python之装饰器(函数)
    1. 装饰器   遵循的原则:     开闭原则:   对功能的扩展开放  对代码的修改是封闭 # 通用装饰器写法 # 存在的意义: 在不破坏原有函数和原有函数调用的基础上,给函数添加新的功能. def wrapper...
    99+
    2023-01-30
    函数 python
  • 如何使用Python中的装饰器函数
    如何使用Python中的装饰器函数在Python编程中,装饰器(decorators)是一种非常有用的工具。它允许我们在不修改原始函数代码的情况下,对函数进行额外的功能扩展。装饰器函数可以在函数执行前后自动执行一些操作,例如记录日志、计时、...
    99+
    2023-10-22
    Python 使用 装饰器函数
  • Python中怎么使用装饰器实现函数的缓存
    这篇文章主要介绍“Python中怎么使用装饰器实现函数的缓存”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python中怎么使用装饰器实现函数的缓存”文章能帮助大家解决问题。装饰器模式在以下场景中被...
    99+
    2023-07-05
  • python中装饰器怎么使用
    这篇文章给大家分享的是有关python中装饰器怎么使用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、装饰器使用场景经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解...
    99+
    2023-06-15
  • 如何进行Python函数装饰器的使用
    如何进行Python函数装饰器的使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。装饰器装饰器的定义关于装饰器的定义,我们先来看一段github上大佬的定义:Functio...
    99+
    2023-06-26
  • Python 函数装饰器详解
    目录使用场景授权(Authorization)日志(Logging)带参数的装饰器在函数中嵌入装饰器装饰器类总结装饰器(Decorators)是 Python 的一个重要部分。简单地...
    99+
    2024-04-02
  • Python函数装饰器应用教程
    目录一、什么是函数装饰器二、函数装饰器的执行时机三、变量作用域四、闭包五、保留函数的元数据七、使用lru_cache缓存函数执行结果八、使用singledispatch实现泛型函数九...
    99+
    2024-04-02
  • python如何使用装饰器缓存函数调用
    这篇文章给大家分享的是有关python如何使用装饰器缓存函数调用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。使用装饰器缓存函数调用你是否曾经编写过一种函数,它执行昂贵的 I/O...
    99+
    2024-04-02
  • python怎样使用装饰器
    这篇文章将为大家详细讲解有关python怎样使用装饰器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。使用装饰器def makebold(f): return&n...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作