Python高阶函数装饰器

简介: Python高阶函数装饰器

“ 从CANoe vTESTstudio版本7开始,支持使用python编辑器编写python脚本。其中CANoe提供了许多API接口给python使用,大大扩展了python的可用性。在python中使用装饰器定义capl中的事件处理程序(on key/on timer等)。对此我们有必要了解什么是装饰器”

装饰器,装饰是包装的意思,器表示工具。所以装饰器字面意思指的是包装用的工具。就像是买的礼物外面的包装盒子一样

可以看出,装饰器有三个特点:

不能改变礼物的本身
包装盒和礼物是一起的
拿出礼物时只会说礼物的名字,不会说包装盒的名称
“ 我们以给别人买生日蛋糕为例,你让服务员给蛋糕包装时,肯定不能让包装盒破坏蛋糕本身;你每次把蛋糕拿出来给别人看时,包装盒必定和蛋糕是一起拿出来的;当你拿出蛋糕时,只会介绍说这是蛋糕,并不会说这是我买的蛋糕和包装盒,对吧!”

那么在python中蛋糕和包装盒分别表示什么呢?蛋糕就是python函数,包装盒就是装饰器

所以,装饰器的特定是:

不能改变函数的内部代码
调用函数时装饰器一并调用
使用函数名调用函数
我们定义一个函数并运行:

def func1():
print("run func1")

func1()
打印的结果为:run func1

现在我想给它添加点特色,就是在打印“run func1”前先打印“program start”。有人说那我把func1函数体改成这样:

def func1():
print("program start")
print("run func1")

func1()
但是如此一来,就破坏了函数func1的函数体,这肯定不是装饰器的作用

那这样呢?

def func1():
print("run func1")

print("program start")
func1()
这样也不符合调用函数func1时一并调用装饰器,因为上面的代码实际上调用了print("program start")和func1(),肯定也不是装饰器的作用

那我利用函数的可参数化呢?

def func1():
print("run func1")

def prog1(func):
print("program start")
func()

prog1(func1)
这样使用的是其他函数调用的,也不符合装饰器的特点

分析:不能改变函数func1的结构,肯定得把函数func1当作参数传入另一个函数prog1中,在另一个函数中实现在调用func1前调用print("program start")。但是又不能通过调用prog1实现,还是要调用func1。怎么办?可以把prog1赋值给func1,以此实现调用func1即是调用prog1

下面这样可以吗?

def func1():
print("run func1")

def prog1(func):
print("program start")
func()

func1 = prog1(func1)

func1()
运行脚本后你会发现报错,报错内容如下:

出问题的点在哪呢?就在func1 = prog1(func1),当把调用prog1(func1)返回的对象赋值给func1时,调用prog1(func1)其实并没有返回值。那么func1就变成了None,最后调用func1肯定就报错了

所以需要在函数prog1的函数体内return一个对象,这个对象需要赋值给func1。由于func1是函数指针,那么prog1 return的对象也应该是一个函数指针。怎么办?可以在prog1函数体内再包一层函数,把这个函数指针返回

def func1():
print("run func1")

def prog1(func):
def wrapfunc():
print("program start")
func()
return wrapfunc

func1 = prog1(func1)

func1()
函数prog1这样的结构就是一个装饰器,使用时只需要把被装饰的函数指针传func1传参给prog1,然后再赋值给func1,如此调用func1就会连装饰器一起调用

但是func1 = prog1(func1)这样的写法麻烦且不具有共通性,所以python提供了一种装饰器的标准用法

def prog1(func):
def wrapfunc():
print("program start")
func()
return wrapfunc

@prog1
def func1():
print("run func1")

func1()
prog1是装饰器函数,func1是被装饰的函数,只需要在定义被装饰的函数前面用@符号引出装饰器函数名称,就实现了把被装饰的函数指针传给调用的装饰器函数然后赋值给被装饰函数指针的功能

结束了吗?并没有!

如果你觉得最后调用的func1还是以前的func1就错了,不信可以打印一下它的名称:

print(func1.name)
打印结果:wrapfunc

为什么?因为func1 = prog1(func1)时,调用prog1(func1)返回的就是wrapfunc函数,然后又赋值给了func1,所以func1已经不是之前的func1了。它重写了函数的名字和注释文档

有解决的办法吗?有!!!

python提供了一个函数functools.wraps解决这个问题

from functools import wraps

def prog1(func):
@wraps(func)
def wrapfunc():
print("program start")
func()
return wrapfunc

@prog1
def func1():
print("run func1")

func1()
@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性

总结:

装饰器本质上是函数,需要编写
函数只有加上后面的括号才是调用,只有函数名,是函数指针
函数指针可以作为参数传参
函数指针作为对象可以赋值给其他的变量
函数体内可以定义其他的函数

目录
相关文章
|
23天前
|
缓存 算法 数据处理
Python入门:9.递归函数和高阶函数
在 Python 编程中,函数是核心组成部分之一。递归函数和高阶函数是 Python 中两个非常重要的特性。递归函数帮助我们以更直观的方式处理重复性问题,而高阶函数通过函数作为参数或返回值,为代码增添了极大的灵活性和优雅性。无论是实现复杂的算法还是处理数据流,这些工具都在开发者的工具箱中扮演着重要角色。本文将从概念入手,逐步带你掌握递归函数、匿名函数(lambda)以及高阶函数的核心要领和应用技巧。
Python入门:9.递归函数和高阶函数
|
3月前
|
开发者 Python
探索Python中的装饰器:从基础到高级应用
本文将带你深入了解Python中的装饰器,这一强大而灵活的工具。我们将一起探讨装饰器的基本概念,它们如何工作,以及如何使用它们来增强函数和类的功能,同时不改变其核心逻辑。通过具体代码示例,我们将展示装饰器的创建和使用,并探索一些高级应用,比如装饰器堆栈和装饰带参数的装饰器。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角,帮助你更有效地使用装饰器来简化和优化你的代码。
|
3月前
|
测试技术 数据安全/隐私保护 开发者
探索Python中的装饰器:从基础到高级应用
装饰器在Python中是一个强大且令人兴奋的功能,它允许开发者在不修改原有函数代码的前提下增加额外的功能。本文将通过具体代码示例,带领读者从装饰器的基础概念入手,逐步深入到高级用法,如带参数的装饰器和装饰器嵌套等。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
2月前
|
测试技术 数据库 Python
Python装饰器实战:打造高效性能计时工具
在数据分析中,处理大规模数据时,分析代码性能至关重要。本文介绍如何使用Python装饰器实现性能计时工具,在不改变现有代码的基础上,方便快速地测试函数执行时间。该方法具有侵入性小、复用性强、灵活度高等优点,有助于快速发现性能瓶颈并优化代码。通过设置循环次数参数,可以更准确地评估函数的平均执行时间,提升开发效率。
120 61
Python装饰器实战:打造高效性能计时工具
|
2月前
|
设计模式 前端开发 Shell
Python装饰器是什么?
装饰器是Python中用于动态修改函数、方法或类功能的工具,无需改变原代码。通过将函数作为参数传递并返回新函数,装饰器可以在原函数执行前后添加额外逻辑。例如,使用`@logger`装饰器可以打印函数调用日志,而`@timethis`则可用于计算函数执行时间。为了保持被装饰函数的元信息(如`__name__`和`__doc__`),可使用`functools.wraps`装饰器。此外,带参数的装饰器可通过嵌套函数实现,如`@timeitS(2)`,以根据参数条件输出特定信息。
93 59
|
3月前
|
缓存 数据安全/隐私保护 Python
python装饰器底层原理
Python装饰器是一个强大的工具,可以在不修改原始函数代码的情况下,动态地增加功能。理解装饰器的底层原理,包括函数是对象、闭包和高阶函数,可以帮助我们更好地使用和编写装饰器。无论是用于日志记录、权限验证还是缓存,装饰器都可以显著提高代码的可维护性和复用性。
58 5
|
3月前
|
测试技术 开发者 Python
探索Python中的装饰器:从入门到实践
装饰器,在Python中是一块强大的语法糖,它允许我们在不修改原函数代码的情况下增加额外的功能。本文将通过简单易懂的语言和实例,带你一步步了解装饰器的基本概念、使用方法以及如何自定义装饰器。我们还将探讨装饰器在实战中的应用,让你能够在实际编程中灵活运用这一技术。
61 7
|
3月前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!
|
3月前
|
程序员 测试技术 数据安全/隐私保护
深入理解Python装饰器:提升代码重用与可读性
本文旨在为中高级Python开发者提供一份关于装饰器的深度解析。通过探讨装饰器的基本原理、类型以及在实际项目中的应用案例,帮助读者更好地理解并运用这一强大的语言特性。不同于常规摘要,本文将以一个实际的软件开发场景引入,逐步揭示装饰器如何优化代码结构,提高开发效率和代码质量。
85 6
|
3月前
|
存储 缓存 Python
Python中的装饰器深度解析与实践
在Python的世界里,装饰器如同一位神秘的魔法师,它拥有改变函数行为的能力。本文将揭开装饰器的神秘面纱,通过直观的代码示例,引导你理解其工作原理,并掌握如何在实际项目中灵活运用这一强大的工具。从基础到进阶,我们将一起探索装饰器的魅力所在。

热门文章

最新文章