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接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性

总结:

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

目录
相关文章
|
2天前
|
缓存 开发者 Python
探索Python中的装饰器
本文将深入探讨Python中一个高级且强大的功能——装饰器。我们将从基本概念开始,逐步解析其工作原理及实际应用。通过具体示例,读者将能够理解如何使用装饰器来扩展函数功能,以及如何利用这一特性优化代码结构。无论是新手还是经验丰富的开发者,都能从中获取有价值的见解。
14 5
|
1天前
|
Python
探索Python编程中的装饰器
【9月更文挑战第18天】本文将深入探讨Python中的一项强大功能——装饰器。通过简化的实例,我们会了解如何创建和使用装饰器来增强函数的功能,同时保持代码的整洁性和可读性。
10 3
|
2天前
|
设计模式 Python
探索Python中的装饰器:从基础到高级应用
本文深入探讨了Python中装饰器的使用,包括其基本定义、实际应用以及如何创建自定义装饰器。通过具体示例,我们将揭示装饰器在函数编程中的强大功能和灵活性,帮助读者更好地理解和运用这一技术。
14 3
|
2天前
|
缓存 数据安全/隐私保护 Python
探索Python中的装饰器
在本文中,我们将深入探讨Python装饰器的概念、应用及其背后的原理。通过具体的代码示例,您将学会如何使用装饰器来扩展函数功能,而无需永久性地修改它们。我们还将了解不同类型的装饰器,包括一元和二元装饰器,并学习如何创建和使用自定义装饰器。预计阅读时间:5分钟。
|
3天前
|
设计模式 缓存 开发者
探索Python中的装饰器:提升代码复用性的利器
本文深入探讨了Python中强大的装饰器功能,揭示了其如何通过元编程和闭包等技术手段,优雅地实现代码的复用与扩展。从基本概念到高级应用,我们将一步步揭开装饰器背后的奥秘,并通过实例展示其在实际项目开发中的巨大价值。无论是想要简化函数调用流程、增强函数功能,还是实现AOP(面向切面编程),掌握装饰器都是每位Python开发者必备的技能。
|
3天前
|
Python
掌握Python装饰器:从基础到高级应用
本文深入探讨了Python装饰器的用法,通过具体示例展示了如何定义和使用方法。同时,文章还涵盖了装饰器的高级应用,包括带参数的装饰器、类装饰器以及如何在标准库中使用装饰器。通过阅读这篇文章,读者将能够更好地理解和利用Python中的装饰器来提高代码的可重用性和可维护性。
|
3天前
|
测试技术 开发者 Python
探索Python中的装饰器:从基础到高级应用
【9月更文挑战第16天】在Python的世界里,装饰器是那些让代码变得更加优雅、模块化的神奇工具。本文将通过实际案例带你了解装饰器的工作原理,并展示如何利用它们简化日常编程任务,同时也会探讨装饰器在高级用法中的潜力。准备好让你的Python代码更加高效和易于维护了吗?让我们开始吧!
12 1
|
1天前
|
设计模式 Python
探索Python中的装饰器:从基础到高级应用
本文深入探讨了Python中装饰器的概念、使用方法以及实际应用。通过具体示例,阐述了装饰器如何增强函数功能,实现代码复用和逻辑分离,旨在帮助读者理解并有效利用这一强大工具。
7 0
|
2天前
|
缓存 监控 测试技术
探索Python中的装饰器:提升代码的灵活性和可维护性
本文深入探讨Python装饰器的概念、用法及优势。通过实例讲解如何利用装饰器增强函数功能、日志记录及性能测试,旨在帮助读者掌握这一强大的工具,提升编程效率与代码质量。
|
3天前
|
缓存 开发者 Python
探索Python中的装饰器:提升代码复用性与可读性
本文旨在深入探讨Python装饰器的概念、实现及其应用。通过实例分析,本文展示了如何利用装饰器提高代码的模块化和重用性,从而优化开发流程。我们将从装饰器的基本定义入手,逐步解析其工作机制,并通过案例展示如何在实际项目中有效利用装饰器。
8 0