首页 > 编程语言 >python装饰器

python装饰器

时间:2024-07-31 21:38:56浏览次数:15  
标签:__ 函数 python de except test 装饰

一前言

环境: win10 python3.10

二 函数中的函数

如果定义了一个函数A,现在想在不影响函数A原先功能的情况下,新增加一些额外的功能,怎么办,下面是一个例子
image

如上,本来原先执行test_except那句话只会打印over那句话,但现在执行test_except却会输出一些另外的东西

这其中有个巧妙地东西就同一个变量名所指的对象不同
原先的test_except指向的就是我们所定义的包含try语句的函数
image

当我们执行de()并赋值给同名变量test_except,在看下
image
如上,这时except依然指向的是一个函数,只不过不再试原来的函数,而是另一个函数de_in

三 装饰器

1 普通装饰器

装饰器就是返回值为另一个函数的函数,只不过它的采用形式有点特别
image
严格来说,上面装饰器函数de的定义还差一步,这个最后面再说

执行结果
image

如上,de为装饰器,test_except为被装饰的函数
结果和之前采用变量赋值的方法来运行几乎是一样的,可以认为这两种改变函数功能的方法几乎是等价的

这里有个细节,de function code 是在 start之前输出的。也就说装饰器函数不是在被装饰函数运行时才开始执行的,而是在被装饰函数在加载的时候就开始执行
在上一小变量赋值部分就可以看到,在执行test_except=de(test_except)时,de函数的主体部分就开始执行了(其中的子函数还为开始执行),而最终的test_except函数(也就是de函数的子函数)还未执行

也就是说,把@de 放在 def test_except的前面,就大致相当于执行下面代码

test_except = de(test_except)

如果被装饰函数需要参数,装饰器函数定义加上形参即可,如下
image

严格来说,上面装饰器函数de的定义还差一步,这个最后面再说

2 多个装饰器

函数可被多个装饰器装饰
image
严格来说,上面装饰器函数的定义还差一步,这个最后面再说
执行结果
image

如上,两个装饰器装饰的函数,其过程大致是这样

@db
@de
就大致相当于执行
test_except = db(de(test_except))
其中de(test_except)先执行,打印出de fuction code,并返回de_in作为结果。然后上面就变成这样
test_except = db(de_in)
这时候,右边先执行,打印出db function code ,并返回db_in作为结果,变化成这样
test_except = db_in

这时候我们输入test_except() ,就会执行db_in,打印出db_in function code 
然后de_in中,它里面还有一个函数会执行,即上一步参数中的函数de_in,打印出de_in function code
然后在执行de_in中,它里面还有一个函数会执行,即第一步的test_except函数
最后打印出over

3 装饰器传入参数

上面的装饰器使用时都没有参数,直接是@decorator的形式,如果要给decorator即装饰器传入参数,则需要把普通装饰器再套在一层函数里面
image
严格来说,上面装饰器函数de的定义还差一步,这个最后面再说
执行结果
image

上图的@dc(8,9)大致相当于执行

test_except = dc(8,9)(tes_except)

之前的普通装饰器是这样

test_except=de(test_except)

其实要点就在于,用dc(8,9)来得到de这个函数。即在普通装饰器基础上,用一个函数来得到de这个函数对象(即de的函数定义)

来看看具体带参数装饰器的执行过程

test_except = dc(8,9)(tes_texcept)

先执行dc(8,9),会打印出dc function code,并返回decorator_de这个函数。就变成这样

test_except = decorator_de(test_except)

这不又是普通装饰器的的第一步了

4 完整的装饰器的定义

之前多次提到,装饰器的定义还差最后一步,也说过变量赋值和@ 这两种方式大致是相同的。
这些所说的就是函数的属性__name__(也就是函数的名称问题)

首先我们用变量赋值的方法,来看下貌似改增加了额外功能的那个函数的前后的名称
image
首先看下赋值前,函数的__name__属性
image

这个结果应该很好理解

再看下赋值后的函数的__name__属性
image

这个前面也讲过,test_except这个名称虽然没有变化,但她执行的对象发生了变化,现在指向了de_in这个函数。所以他的__name__变成了de_in

如果是用之前的装饰器定义去运行,也会发生相同的结果,__name__最终也会变成de_in
image

image

这样看上去功能也没啥影响,但有时一些依赖函数签名的地方就会报错,以防万一,在使用@decorator这种形式时,我们需要把__name__的值变回为原来最开始的函数名称(即被装饰的函数名)
所以严格的装饰器定义是这样

import functools
def decorator(f):
	xxxxx
	# 在装饰器增加下面这行,改回__name__的值
	@functools.wraps(f)
	
	def wrapper(*args, **kw):
		xxxx
		f(*args, **kw)
	return wrapper

# 上面的@functools.wraps(f)也可以替换成wrapper.__name__ = func.__name__

现在我们来试一下
image

image

标签:__,函数,python,de,except,test,装饰
From: https://www.cnblogs.com/MyRecords/p/18334893

相关文章

  • Python - Built-in Exceptions: Python Exceptions Class Hierarchy
     Figure20.4:Built-inexceptionsTheclassBaseExceptionisthebaseclassofallthebuilt-inexceptionclasses.FromBaseException,fourclassesnamedException,SystemExit,KeyboardInterruptandGeneratorExitarederived.Alltheremainingbuilt-in......
  • Python - Strategies to handle exceptions in your code
    Therearetwoapproachesthatcanbefollowedwhenwewanttodealwithexceptionsthatoccurduetounusualevents:LBYL-LookBeforeYouLeapEAFP-EasiertoAskforForgivenessthanPermissionIntheLBYLapproach,weavoidexceptions,whileinthe......
  • 全网最适合入门的面向对象编程教程:29 类和对象的Python实现-断言与防御性编程和help函
    全网最适合入门的面向对象编程教程:29类和对象的Python实现-断言与防御性编程和help函数的使用摘要:在Python中,断言是一种常用的调试工具,它允许程序员编写一条检查某个条件。本文主要介绍了断言的应用场景和特点以及assert语句的使用,同时介绍了防御性编程和help()函数......
  • Python入门知识点 10--闭包与装饰器
    一、直接与间接程序开发潜规则生活中:   有台电脑,他的硬盘空间不够了,里面的资料我不能动,也不能删,咋办   1.加装硬盘--直接解决--前提是我的电脑能加装   2.插个u盘--间接解决-->没有特别的要求,比较灵活   开发潜规则:   代码拓展-->开放-->可......
  • python log运算如何写
    Python中用于计算对数的log()方法,是Python入门基础中的必会的方法,需要的朋友可以参考下。log()方法返回x的自然对数,x>0。语法以下是log()方法的语法:import math math.log( x )注意:此函数是无法直接访问的,所以我们需要导入math模块,然后需要用math的静态对象来调用......
  • Python - operator module
    >>>list(map(lambdax,y:x*y,[1,2,3,4],[5,6,7,8]))[5,12,21,32]Herewehavecalledthemapfunctionandsentalambdaexpressionasfirstargument.Insteadofthelambdafunction,youcansendoperator.mul.>>>list(map(operator......
  • Python操作excel常用操作介绍,入门首选
            使用Python操作Excel文件有许多常用操作。以下是一些常见的操作及其简要描述,下面是全面详细的示例,展示如何使用Python操作Excel文件,我们将使用pandas和openpyxl库来进行各种操作。常用库pandas:用于数据分析和处理,支持读取和写入Excel文件。openpyxl:用于读......
  • Python蒙特卡罗(Monte Carlo)模拟计算投资组合的风险价值(VaR)
    原文链接:http://tecdat.cn/?p=22862原文出处:拓端数据部落公众号如何使用Python通过蒙特卡洛模拟自动计算风险值(VaR)来管理投资组合或股票的金融风险。金融和投资组合风险管理中的VaR?VaR是"风险价值"的缩写,是许多公司和银行用来确定其公司内部金融风险水平的工具。风险值是为......
  • Python 元类深析:定制类创建的高级工
    元类是Python中一个强大而高级的特性,它允许我们自定义类的创建过程。本文将详细介绍Python元类的概念、工作原理以及常见用途。一. 什么是元类简单来说,元类就是用来创建类的类。在Python中,类也是对象,而元类就是用来创建这些类对象的。我们知道类是用来创建对象的......
  • 【视频讲解】Python用LSTM、Wavenet神经网络、LightGBM预测股价
    原文链接:https://tecdat.cn/?p=37184原文出处:拓端数据部落公众号 分析师:YuyanYe在金融科技的浪潮中,量化投资方法以其数据驱动和模型导向的特性,日益成为资本市场分析的重要工具。特别是,长短期记忆网络(LSTM)、Wavenet以及LightGBM等先进的机器学习算法,因其在时间序列预测中的卓......