Python中的函数装饰器

python函数封装 在Python中,使用关键字。 阅读详情

先上文档 Function definitions ,如果只是想简单的知道怎么使用函数装饰器,那先看看下面这个例子:

def makebold(fn):
    print("I'm bold")
    def wrapped():
        return "<b>" + fn() + "</b>"
    return wrapped

def makeitalic(fn):
    print("I'm italic")
    def wrapped():
        return "<i>" + fn() + "</i>"
    return wrapped

@makebold
@makeitalic
def say():
    return "Hello Python"

print(say())

#Outputs:
# I'm italic
# I'm bold
# <b><i>Hello Python</i></b>

为了理解装饰器,首先必须要知道的一点是在Python中函数也是一种对象,知道了这一点对我们理解后续内容是很有帮助的。下面来看一个例子:

def shout(word="yes"):
    return word.capitalize() + "!"

print(shout())
#outputs: "Yes!"

#前面我们提到函数也是一种对象类型,
#所以你可以像指派其他对象一样把一个函数指派个一个变量,
#注意:在这里我们并没有用圆括号,因为这里并没有调用执行函数调用,仅仅是
# 把函数'shout'指派给了'scream'变量,意味着你可以通过scream调用shout。
scream = shout

print(scream())
#outputs: "Yes!"


print(id(shout))
print(id(scream))
#我们打印来看看两个函数对象的地址:
# 都为 4338464288


#不仅如此,你可以把原来的名字'shout'移除掉,仍然可以调用'scream'对象
del shout
try:
    print(shout())
except NameError as e:
    print(e)
    #outputs: name 'shout' is not defined

print(scream())
#outputs: Yes!

Python函数中一个有趣的属性是我们可以在函数内部定义另一个函数,也就是嵌套:

def talk():
    def whisper(word="yes"):
        return word.lower() + "..."

    #定义函数whisper后就立即调用它
    print(whisper())


#当你每次调用'talk'的时候,函数'whisper'就会被定义,然后紧接着就被调用。
talk()
#outputs: "yes..."


#但是有一点需要知道,'whisper'并不会出现在'talk'外。
try:
    print(whisper())
except NameError as e:
    print(e)
    #outputs: name 'whisper' is not defined

好了,到了这里想必你也该知道其实函数就是一种对象类型:它能被指派给一个变量;能够被定义在另一个函数内部。这也就意味着一个函数能够返回另一个函数:

def getTalk(kind="shout"):

    def shout(word="yes"):
        return word.capitalize() + "!"

    def whisper(word="yes"):
        return word.lower() + "..."

    if kind == "shout":
        #注意:不要在后面加圆括号,这里并没有调用函数,而是返回一个函数对象
        return shout
    else:
        return whisper

talk = getTalk()
#你可以看到talk在这里就是一个函数对象
print(talk)
#outputs: <function getTalk.<locals>.shout at 0x10217b7b8>

#这里我们才调用这个函数对象
print(talk())
#outputs: Yes!

#当然你也可以直接调用:
print(getTalk("whisper")())
#outputs: yes...

你也可以return 一个函数,也可以把一个函数当做参数传递:

def doSomethingBefore(func):
    print("I do something before then I call the function you gave me")
    print(func())

doSomethingBefore(scream)
#outputs: I do something before then I call the function you gave me
#         Yes!

到了这里,你基本就已经具备了链接装饰器的基本条件了装饰器其实就是一个种”wrappers”, 意思就是这种”wrappers”可以让你在它们装饰的函数前后执行一些其他的代码,而不用修改函数本身。

下面我们来手写一个装饰器:

def my_shiny_new_decorator(a_function_to_decorate):

    def the_wrapper_around_the_original_function():

        print("Before the function runs")
        a_function_to_decorate()

        print("After the function runs")

    return the_wrapper_around_the_original_function

def a_stand_alone_function():
    print("I am a stand alone function, don't you dare modify me")

a_stand_alone_function()
#outputs: I am a stand alone function, don't you dare modify me

a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function_decorated()
#outputs:
#Before the function runs
#I am a stand alone function, don't you dare modify me
#After the function runs

这里其实就是把一个函数当做一个参数,传递到一个接收一个函数作为参数的嵌套函数内,嵌套函数内调用的才是我们真正传递进去的函数,可以看到在调用该函数前后我们可以执行一些额外的工作。现在,你可能想要在每次调用a_stand_alone_function函数的时候,都调用装饰好的函数a_stand_alone_function_decorated而不是调用装饰前的函数本身。这个也好办,我们只需用my_shiny_new_decorator的返回值来重写a_stand_alone_function就好了。

a_stand_alone_function = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function()
#outputs:
#Before the function runs
#I am a stand alone function, don't you dare modify me
#After the function runs

接下来我们可以用装饰器语法来改写前面的例子:

@my_shiny_new_decorator
def another_stand_alone_function():
    print("Leave me alone")

another_stand_alone_function()  
#outputs:  
#Before the function runs
#Leave me alone
#After the function runs

恩,其实也就是这么简单。@decorator其实就是下面语句的快捷标签:

another_stand_alone_function = my_shiny_new_decorator(another_stand_alone_function)

装饰器其实就是装饰器设计模式 的一种Python化变体。Python中内嵌了很多经典的设计模式,用来使开发变得更容易(比如:iterators)。

当然,你可以一个个的累积装饰器函数:

def bread(func):
    def wrapper():
        print("</''''''\>")
        func()
        print("<\______/>")
    return wrapper

def ingredients(func):
    def wrapper():
        print("#tomatoes#")
        func()
        print("~salad~")
    return wrapper

def sandwich(food="--ham--"):
    print(food)

sandwich()
#outputs: --ham--
sandwich = bread(ingredients(sandwich))
sandwich()
#outputs:
#</''''''\>
# #tomatoes#
# --ham--
# ~salad~
#<\______/>

也可以使用装饰器语法:

@bread
@ingredients
def sandwich(food="--ham--"):
    print(food)

sandwich()
#outputs:
#</''''''\>
# #tomatoes#
# --ham--
# ~salad~
#<\______/>

你也可以交换下装饰器顺序(对顺序敏感的):

@ingredients
@bread
def strange_sandwich(food="--ham--"):
    print(food)

strange_sandwich()
#outputs:
##tomatoes#
#</''''''\>
# --ham--
#<\______/>
# ~salad~

更多阅读:参考这里

Python 使用装饰器 decorator 修改函数行为 在 Python 中,装饰器是一种特殊的高阶函数,它使开发者能够在现有函数(或方法)中添加新功能,而无需添加或更改函数中的任何内容。标准装饰器是一个函数,它接受一个函数作为实参,返回一个内部函数,执行装饰工作。在一个函数上,可以使用多个装饰器,这可以通过链接装饰器实现。值得一提的是,装饰器在简化代码和以简洁的方式添加行为方面非常有用,但其代价是在执行过程中产生额外的开销。我们在调试程序的时候,需要更详细的函数调用信息,然而,使用了装饰器后,当我们在被装饰的函数上调用。装饰器,它返回了一个内部函数。 阅读详情

相关推荐

【Python函数式编程】——装饰器

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值 也是一个函数对象。它经常用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,装饰器是解决这类问题的绝佳设计。

Python全栈系列 2万+

python 手写装饰器

1. 代码 # 手写一个装饰器 def retry(func): def wrager(*args, **kwargs): ret = func(*args, **kwargs) max_retry = 3 number = 0 if not ret: while number < max_retry: number = number + 1

高压锅博客 424

Python函数的函数——装饰器

在 Python 中,装饰器是一种设计模式,用于在不修改原有函数代码的情况下,给函数添加新的功能。装饰器本质上是一个函数,它接收一个函数作为参数,返回一个新的函数。

微小冷的学习笔记 1049

Python从小白到高手实现系列八十二:包装过的函数

(4)保存内省的装饰器 使用装饰器的常见错误是在使用装饰器时不保存函数元数据(主要是文档字符串和原始函数名)。前面所有示例都存在这个问题。装饰器组合创建了一个新函数,并返回一个新对象, 但却完全没有考虑原始函数的标识。这将会使得调试这样装饰过的函数更加困难,也会破坏可 能用到的大多数自动生成文档的工具,因为无法访问原始的文档字符串和函数签名。但我们来看一下细节。假设我们有一个虚设的(dummy)装饰器,仅有装饰作用,还 有其他一些被装饰的函数:48 第2章 语法最佳实践—类级别以下。

Mr_Roki的博客 1083

《Ventoy 制作系统安装 U 盘的具体步骤》

然后您可以在电脑的磁盘管理中对 U 盘进行快速格式化,选择 FAT32 或 NTFS 文件系统。至此,Ventoy 系统安装 U 盘就制作完成了。您可以在需要安装系统的电脑上,从 U 盘启动,然后选择相应的系统镜像进行安装。安装完成后,将您需要的操作系统镜像文件(如 Windows、Linux 等的 ISO 格式镜像)复制到 U 盘的根目录。在安装程序中,选择您插入的 U 盘设备,确保选择正确,以免误操作。2. 确认选择的 U 盘盘符正确,防止误操作导致其他磁盘数据丢失。点击“安装”按钮,等待安装完成。

jiyiwangluokeji的博客 2671

使用bandersnatch搭建pypi 本地镜像源(20211026)

需求背景:公司内网不能联网,同时开发工作需要各种python的模块,因此需要搭建一个pypi的本地镜像源。 参考网上的方法,总结了大致有下面几种方式搭建pypi本地源: devpi: 企业内网利用devpi搭建pypi私服 - 简书 pip2pi: https://yangfannie.com/1439.html pypiserver: https://zhongneng.github.io/2019/02/16/creat-pip/ bandersnatch:基于bandersnatch搭...

liurizhou的博客 6468

python-写一个装饰器

一直都知道python有这样一个功能,但是没有遇到过,今天写一个程序,分步对图像进行处理,我想观察每个处理的时长看哪些操作比较耗时,我本来想这样写: import time st = time.time() func(*args, **kw) ptint(time.time()-st) 但是这样要在每步处理函数前后都添加代码,麻烦不说代码不好管理,这时候想到了装饰器 def runTime(fu...

yywxl的博客 664

某二级支行网络的设计与实现——配置脚本(1)

【代码】某二级支行网络的设计与实现——配置脚本(1)

u010311846的博客 577

python--写一个装饰器,统计函数调用时间

1. 手写一个装饰器 import time def timer(func): """ 用于计时的装饰器函数 :param func: 被装饰函数 :return: 闭包函数,封装了自定义行为与被装饰函数的调用 """ def wrapper(*args, **kwargs): """ 闭包函数 :param args: 被装饰函数的位置参数 :param kwargs: 被装饰函数的关键字

高压锅博客 1222

告别Failed to start错误!保姆级教程:用Ubuntu20.04安装盘搞定GRUB与系统服务修复

本文提供Ubuntu20.04系统启动失败的专业修复指南,详细讲解如何利用安装盘解决GRUB与系统服务问题,避免重装系统导致的数据丢失。涵盖分区挂载、chroot环境操作、服务诊断与修复等实用技巧,帮助用户高效恢复系统正常运行。

weixin_32578161的博客 331

Nvidia Driveos SDK/PDK介绍

NVIDIA DRIVEOS SDK/PDK介绍

u011803281的博客 2178

【Python】装饰器函数

以上是装饰器函数的一些基本内容, 要尝试着敲一遍才能理解, 如果第一遍看不懂的话,不要慌, 因为装饰器,闭包函数,*操作符等算是python中的中高级内容了, 我也是学习了好多遍,虽然实际中从没用过,但是学学对于理解pyhton的特性还是很有帮助的, 最后, 希望这篇文章可以帮到你!

享你所想 1603

10、数据挖掘与轨迹生成技术:FSSEMiner与CondTraj - GAN的探索

本文介绍了两种先进的数据处理技术:FSSEMiner算法用于从动态属性图中挖掘频繁顺序子图演化模式,揭示如交通流和疾病传播等复杂系统的演化规律;CondTraj-GAN是一种端到端的条件生成对抗网络,能够生成高质量的合成车辆轨迹,解决真实轨迹数据因隐私问题难以获取的挑战。通过实验评估与真实数据集验证,两种技术在可扩展性、实用性及生成质量方面均表现出色,并在交通管理、城市规划、自动驾驶研发等领域具有广泛应用前景。

grafana8visual的博客 88

Python中的装饰器函数

在Python编程中,装饰器是一种非常强大的工具,它允许我们以非侵入式的方式增强函数或方法的功能。装饰器本质上是一个函数,它接受一个函数作为参数并返回一个新的函数。在Python中,闭包指的是一个函数记住了其外部函数的变量并可以访问和操作这些变量。装饰器通常是一个闭包,因为它内部定义了一个函数(闭包),这个函数引用了外部函数的变量。装饰器是Python中一个非常强大的功能,它提供了一种优雅的方式来增强函数的功能。装饰器工厂本身也是一个闭包,因为它返回的是一个装饰器(闭包)。

qq_45633975的博客 1513

使用Mask2Former和X-Decoder训练自定义数据集及结果复现报告

本报告记录了使用MMDetection框架中的Mask2Former和X-Decoder模型在自定义数据集上的训练过程。报告包含环境配置、数据集准备、模型训练与优化(解决了Mask2Former的PQ值异常问题)、性能评估等关键环节。详细展示了从数据集转换(将客户提供的COCO格式数据适配MMDetection框架)、配置文件修改、到最终模型训练和评估的全流程。特别针对Mask2Former训练中的PQ值异常问题提供了解决方案,并对比了两种模型在自定义数据集上的表现。报告还包含完整的代码实现和技术细节。

huanghm88的专栏 1099

VTK 显示大量点云数据及交互(点云拾取、着色、测量等)功能

VTK (Visualization Toolkit) 是一个强大的开源可视化库,非常适合处理点云数据。下面将介绍如何使用 VTK 显示大量点云数据,并实现点云拾取、着色、测量等功能。

深之JohnChen的专栏 1997

Python装饰器:函数装饰器①

func()我们可以使用")Hello!在这个例子中,是一个装饰器,它接受函数say_hello作为参数,并返回一个新的函数wrapper。当调用say_hello时,实际上调用的是wrapper函数。装饰器是 Python 中一个非常强大的工具,可以用来扩展和修改函数或方法的行为。通过装饰器,我们可以在不修改原始代码的情况下为函数添加额外的功能。在实际开发中,装饰器有很多应用场景,包括日志记录、访问控制、性能优化等。希望本文能够帮助你更好地理解和使用 Python 中的装饰器。

结合项目案例,记录点点滴滴,自己回顾,分享他人o__o 2902

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

python-函数装饰器,类装饰器,属性装饰器

理解装饰器 python中的装饰器看起来类似java中的注解,然而并不相同,Python中装饰器本质是一个函数,只是这个函数可以在不改变别的函数的基础上,增加一些功能,想要理解装饰器,首先了解一下闭包这个概念 闭包 通俗点说,函数A中定义了另外一个函数B,这里A称为外函数,B称为内函数,所谓的闭包就是,内涵数B运用了外函数A定义的变量C,并且外函数的返回值是内函数的引用,这就是闭包,给段代码了解下: def A(number): C= 10 def B(): return int(number) +

m0_47671192的博客 1851

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

python 成员函数装饰器_python中的装饰器详解

在了解装饰器的之前一定要先了解函数作为参数传递, 什么是函数内嵌,请参考我之前写的博客函数简介因为在python里面,函数也是对象,也可以作为参数进行传递.python装饰器本质也是一种特殊函数,它接收的参数是函数对象,然后动态地函数参数添加额外的功能,而不用修改原有的函数对象.python装饰器传入的参数是函数,返回的值也是函数!python装饰器思想有点类似设计模式的装饰模式, 其意图是动态地...

weixin_35917193的博客 953

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Python函数:装饰器

本章介绍了python函数中的装饰器

2403_86719076的博客 2333

python函数装饰器和php函数装饰器

python函数装饰器和php函数装饰器 python里面有一类特别有趣的语法糖名叫装饰器(Decorator).也就是给定的特定的语法结构允许对函数进行包装,添加特定的功能. 如果只看名字,可能会觉得和其他面向对象语言中的装饰器模式相似.可以参考装饰器模式(装饰设计模式)详解 装饰器的讨论 装饰器在python3.0之前并不是一个语法糖( syntax candy).一开始,他是因为python的语法特性而被人借用的常见开发方式.原因在于python糅杂了函数式编程的语法.允许吧函数作为参数参数和返回值使

南浦 354

python之装饰器,多重装饰器,多层函数装饰器

理解装饰器之前先要理解闭包 闭包 定义:在一个函数内部的函数,同时内部函数又引用了外部函数的变量。 本质:闭包是将内部函数和外部函数的执行环境绑定在一起的对象。 优点:内部函数可以使用外部变量。 缺点:外部变量一直存在于内存中,不会在调用结束后释放,占用内存。 作用:实现python装饰器。 闭包三要素: – 必须有一个内嵌函数。 – 内嵌函数必须引用外部函数中变量。 – 外部函...

weixin_44955304的博客 521

Python 进阶:函数装饰器

本小节主要梳理函数装饰的用法,循序渐进,逐层增加条件,加大复杂度和难度。环境说明:Python 3.6、windows11 64位。

明而决之 3097

python高阶知识之函数装饰器详解

装饰器(decorator)是函数一种高阶用法,定义时需要满足几个条件:1 函数内定义嵌套函数并返回该函数(这种叫函数闭包)2 将函数作为参数传入这样看来实现也不是很复杂,平常我们也会经常用到装饰器函数,比如类中的@staticmethod,@classmethod,Flask框架中的@app.route()等。

kymppcds的博客 1326

python —— 高阶函数、嵌套函数与装饰器

高阶函数、嵌套函数与装饰器的使用

julong187的博客 1448

python装饰器函数-python装饰器1:函数装饰器详解

先混个眼熟谁可以作为装饰器(可以将谁编写成装饰器):函数方法实现了__call__的可调用类装饰器可以去装饰谁(谁可以被装饰):函数方法类基础:函数装饰器的表现方式假如你已经定义了一个函数funcA(),在准备定义函数funcB()的时候,如果写成下面的格式:@funcAdef funcB():...表示用函数funcA()装饰函数funcB()。当然,也可以认为是funcA包装函数funcB。它...

weixin_37988176的博客 431
上一篇: Python中的默认参数值
下一篇: 基于Python Web应用的Web服务器之间的比较
Willib
博客等级 码龄14年 83粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值