Python装饰器使用方法全面梳理
作者:专注算法的马里奥学长 发布时间:2023-04-27 08:22:15
1 装饰器背景知识
1.1 基本概念
装饰器(Decorator)是 Python 中一种函数或类,用来修饰其他函数或类。装饰器可以改变被装饰函数的行为,或者在调用被装饰函数之前和之后增加额外的操作。装饰器的语法是使用 @ 语法符,在函数定义之前增加装饰器函数的名称。
@decorator_func
def my_func():
pass
1.2 应用场景
代码重用:装饰器可以让我们在不更改原函数代码的情况下,为其添加额外的功能。
日志记录:装饰器可以记录函数的调用日志,帮助我们追踪程序的运行情况。
权限控制:装饰器可以用来实现函数级别的权限控制,只允许特定的用户访问特定的函数。
缓存:装饰器可以用来缓存函数的返回值,避免重复计算。
类型检查:装饰器可以用来在函数调用前检查参数的类型是否符合要求。
装饰器可以让你在函数或类的定义中添加额外的逻辑,而不更改它们的实现。
2 简单的装饰器代码
def decorator_func(func):
def wrapper():
print("Before calling the function")
func()
print("After calling the function")
return wrapper
@decorator_func
def my_func():
print("Inside the function")
my_func()
# Output: Before calling the function
# Inside the function
# After calling the function
上面展示了最简单的装饰器示例代码。在代码中,我们建立了一个名为decorator_func
的装饰器和一个名为my_func
函数。
装饰器外部的return必须为装饰器的内部函数,不含括号。通过代码结构可以看出,装饰器本身也是一个闭包。
在定义装饰器
decorator_func
时,括号中的’func’指代被装饰器装饰的函数,在这段代码中指代的就是my_func
函数。在被装饰器装时候,函数的实际执行执行顺序变成了内部函数
wrapper
所指定的顺序。即先执行print(“Before calling the function”);再执行func()指代的my_func函数;最后执行print(“After calling the function”)。本段代码的最终输出为:Before calling the function;Inside the function;After calling the function
3 使用装饰器记录函数执行次数
def cal_times(func):
l=[]
def wrapper(*var):
l.append('1')
func(*var)
print("函数执行了%s次"%(len(l)))
return wrapper
@cal_times
def my_func(i):
print('%s的平方是%s'%(i,i**2))
my_func(5)
my_func(6)
在my_func(i)
函数中,我们增加了形参的输入,因此,在装饰器中,也要为之做出更改。此处装饰器中的wrapper函数我们使用*var
传参,这种设计方式的优点是可以让这个装饰器适用于任何函数。
再加入了cal_times
装饰器后,函数每运行一次,都会使列表l
添加一个1,这样可以计算函数的运行次数。这段代码的运行结果如下:
4 带参数的装饰器
装饰器与函数一样,也可以带入参数,我们在第二节的基础上,对代码做出如下修改:
def decorator_func(param1, param2):
def decorator(func):
def wrapper():
print("Before calling the function with params:", param1,param2)
func()
print("After calling the function")
return wrapper
return decorator
@decorator_func("hello", "world")
def my_func():
print("Inside the function")
my_func()
这段代码使用了装饰器来在my_func
函数调用前后打印额外的信息,并且装饰器函数decorator_func
接受两个参数,在调用wrapper
函数时使用这两个参数。
最终,代码将输出:
Before calling the function with params: hello world; Inside the function;After calling the function。
如果同时还有字典类型的参数传入,可以使用(*var,**_var)进行解决
5 装饰器处理有返回值的函数
前面我们定义的函数都是执行某种功能,不涉及到return的相关操作。当涉及到处理有返回值的函数时,对于内部函数我们应该使用一个变量将函数的运行结果保存起来,并放在内层函数的return中。为了实现这一功能,我们将第三部分的代码做出如下修改:
def cal_times(func):
l=[]
def wrapper(*var):
l.append('1')
result = func(*var)
print("函数执行了%s次"%(len(l)))
return result
return wrapper
@cal_times
def my_func(i):
print('%s的平方是%s'%(i,i**2))
return i**2
a = my_func(5)
b = my_func(6)
print(a,b)
对于这个装饰器,我们在内部函数wrapper
使用result保存运行结果,并将result return,这样a与b就可以被正常的赋值,运行结果如下图。
而如果不执行保存result并return,a和b将不会得到任何值:
来源:https://blog.csdn.net/nkufang/article/details/128761627


猜你喜欢
- 本文实例讲述了php实现的验证码文件类。分享给大家供大家参考。具体如下:<?php/*** @file* @version 1.0*
- 我们在网页中使用CSS来设置网页、表格和字体大小,一般使用的是网络上较流行的9磅字:<STYLE type=TEXT/CSS
- 对于Python开发用户来讲,PIP安装软件包是家常便饭。但国外的源下载速度实在太慢,浪费时间。而且经常出现下载后安装出错问题。所以把PIP
- 取反运算符的原理:1.对3取反:(取4位二进制)①化为二进制:3→0011②对二进制结果取反:0011→1100③对结果先取反再加1:110
- 本文实例讲述了Python实现批量转换文件编码的方法。分享给大家供大家参考。具体如下:这里将某个目录下的所有文件从一种编码转换为另一种编码,
- 0. 简介上篇博客介绍了goroutine的创建、执行和退出的过程,并且提及了在协程切换时涉及的调度循环,本篇博客我们就来探究一下其他情形引
- 摘要: 有个C++项目是读取配置参数文件并打印对应的结果,后来需要多次修改配置文件并运行,于是想到写个python脚本执行这一过程。写一个测
- 本文介绍了使用python wasmtime来访问rust库的便捷方法,步骤极其简练,可以在生产环境中使用。安装rust target wa
- 最近写一个BootStrap页面...因为功能需要所以决定一个页面解决所有问题,然后用jQuery来动态显示功能....然而这样做的话页面会
- Anaconda安装:anaconda官方下载地址https://www.anaconda.com/products/individual注
- 本文实例讲述了js自定义trim函数实现删除两端空格功能。分享给大家供大家参考,具体如下:兼容IE低版本浏览器,以及其他一些低版本脚本的浏览
- 纯代码通过神经网络实现线性回归的拟合参考链接中的文章,有错误,我给更正了。并且原文中是需要数据集文件的,我直接给替换成了一个数组,采用直接赋
- 定时关机,功能:windows下,用户按照一定格式输入关机时间,系统到指定时间自动关闭 思路:从用户输入获取指定时间 分别以时分秒减去当前时
- AES简介高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这
- 安装包 PyCharm笔者使用PyCharm2018.3.2,请根据机器是64位还是32位来选择对应的PyCharm版本。(相信绝大部分人都
- 原文网址:gradio.app/sharing-you…1.分享演示share=True通过在方法中设置,可以轻松公开
- 1、检查数据库完整性dbcc checkdb(test)--通过加tablock提高速度 dbcc checkdb(test) with t
- 在页面中自定义了changejs函数后页面提示错误:Active Server Pages 错误 'ASP 0138' 嵌套
- 一、单字节SQL注入MYSQL的SQL注入已经由来已久,以下是普遍采用的注入步骤:1、在GET参数上加一个/*或者#(mysql专有的注释)
- public function json_product_list($where, $order){ global $_M; $this-&