python装饰器底层原理

news/2025/1/21 21:51:17/文章来源:https://www.cnblogs.com/mybook000/p/18684513

什么是装饰器

装饰器是Python中的一种特殊函数,主要用于修改或扩展其他函数或方法的功能,而无需修改函数本身的代码。它们通常通过在函数定义前加上@装饰器名称来使用。

@decorator_function
def my_function():pass
​
 
 

装饰器的基本结构

一个基本的装饰器包含一个函数,它接受另一个函数作为参数,并返回一个新的函数。这个新的函数通常会在调用时执行一些附加操作,然后调用原始函数。

def simple_decorator(func):def wrapper():print("Something is happening before the function is called.")func()print("Something is happening after the function is called.")return wrapper
​
 
 

使用该装饰器:

@simple_decorator
def say_hello():print("Hello!")say_hello()
​
 
 

输出:

Something is happening before the function is called.
Hello!
Something is happening after the function is called.
​
 
 

装饰器的底层原理

为了理解装饰器的底层原理,我们需要了解以下几个方面:

1. 函数是对象

在Python中,函数是第一类对象。这意味着函数可以作为参数传递给另一个函数,可以作为另一个函数的返回值,也可以赋值给变量。

def foo():print("Hello from foo")bar = foo
bar()
​
 
 

输出:

Hello from foo
​
 
 

2. 闭包

闭包是一种函数,它保留了定义它的环境中的变量。装饰器利用了闭包来包装函数并添加额外的功能。

def outer_func(msg):def inner_func():print(msg)return inner_funchi_func = outer_func("Hi")
hi_func()
​
 
 

输出:

Hi
​
 
 

3. 高阶函数

装饰器本质上是高阶函数,它们接受函数作为参数,并返回一个新函数。

def decorator_function(original_function):def wrapper_function():print("Wrapper executed this before {}".format(original_function.__name__))return original_function()return wrapper_function@decorator_function
def display():print("display function ran")display()
​
 
 

输出:

Wrapper executed this before display
display function ran
​
 
 

常见装饰器模式

无参数装饰器

这是最基本的装饰器模式。它不接受任何参数,只接受一个函数作为参数。

def my_decorator(func):def wrapper():print("Something is happening before the function is called.")func()print("Something is happening after the function is called.")return wrapper
​
 
 

带参数的装饰器

带参数的装饰器可以接受额外的参数。实现这种装饰器时,需要再嵌套一层函数。

def decorator_with_args(arg1, arg2):def decorator(func):def wrapper(*args, **kwargs):print(f"Arguments passed to decorator: {arg1}, {arg2}")return func(*args, **kwargs)return wrapperreturn decorator@decorator_with_args("Hello", "World")
def say_hello():print("Hello!")say_hello()
​
 
 

输出:

Arguments passed to decorator: Hello, World
Hello!
​
 
 

类装饰器

类装饰器通过实现 __call__方法,可以像函数装饰器一样工作。

class ClassDecorator:def __init__(self, func):self.func = funcdef __call__(self, *args, **kwargs):print("ClassDecorator: Before the function call.")result = self.func(*args, **kwargs)print("ClassDecorator: After the function call.")return result@ClassDecorator
def say_hello(name):print(f"Hello, {name}!")say_hello("Alice")
​
 
 

输出:

ClassDecorator: Before the function call.
Hello, Alice!
ClassDecorator: After the function call.
​
 
 

装饰器的实际应用

日志记录

装饰器可以用于记录函数调用的日志。

def log_decorator(func):def wrapper(*args, **kwargs):print(f"Function {func.__name__} called with arguments {args} and keyword arguments {kwargs}")return func(*args, **kwargs)return wrapper@log_decorator
def add(x, y):return x + yresult = add(5, 3)
​
 
 

输出:

Function add called with arguments (5, 3) and keyword arguments {}
​
 
 

访问控制与权限验证

装饰器可以用于检查用户是否具有执行某些操作的权限。

def require_authentication(func):def wrapper(user, *args, **kwargs):if not user.is_authenticated:print("User is not authenticated.")returnreturn func(user, *args, **kwargs)return wrapper@require_authentication
def view_profile(user):print(f"Displaying profile for {user.name}")# 假设User类和user对象已经定义
view_profile(user)
​
 
 

缓存

装饰器可以用于缓存函数的结果,提高性能。

def cache(func):cached_results = {}def wrapper(*args):if args in cached_results:return cached_results[args]result = func(*args)cached_results[args] = resultreturn resultreturn wrapper@cache
def compute_square(n):return n * nprint(compute_square(4))
print(compute_square(4))  # 这次将使用缓存结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/873004.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《操作系统真相还原》实验记录2.7——生产者与消费者问题

本节实现内容如下: ① 环形缓存区的结构体创建; ② 环形键盘缓冲区的创建; ③ 生产者消费者问题剖析;一、生产者与消费者问题简述我们知道,在计算机中可以并行多个线程,当它们之间相互合作时,必然会存在共享资源的问题,这是通过“线程同步”来解决的,而诠释“线程同步…

CTF-web第一步!

本次的题比较简单,适合我这种入门学者。CTF菜狗杯的web2 c0me_t0_s1gn。进入靶场打开F12会得到前一半。在控制台复制函数give_flag()会得到另一半。 这样就完成了。

P1183 多边形的面积-向量的用法

原题链接 https://www.luogu.com.cn/problem/P1183 题目描述 给出一个没有缺口的简单多边形,它的边是垂直或者水平的,要求计算多边形的面积。 xOy 的笛卡尔平面上,它所有的边都平行于两条坐标轴之一。然后按逆时针方向给出各顶点的坐标值。所有的坐标值都是整数,因此多边形…

蓄水池漂浮物识别摄像机

蓄水池漂浮物识别摄像机具有高效的图像识别功能。通过高清晰度的摄像头捕捉到蓄水池表面的图像,并通过人工智能技术进行快速准确的漂浮物识别。这种摄像机可以自动检测出池面上的漂浮物,并生成相应报警信息。该摄像机支持多种智能算法分析,并通过智能算法对数据进行综合分析…

行为智能识别摄像机

行为智能识别摄像机通过结合人工智能技术和监控技术,实现了对各种行为动作的自动识别和分析,在提高安全性、减少事故发生率方面具有重要意义。随着科技的不断进步和应用范围的扩大,相信这种先进设备将会在更多领域得到广泛应用。行为智能识别摄像机是一种结合了人工智能技术…

AI人数智能统计监测摄像头

AI人数智能统计监测摄像头具有高效的图像识别功能。通过先进的图像处理算法,可以快速准确地识别出场景中的人群,并进行实时统计。无论是密集的人流场所还是较为稀疏的区域,这种摄像头都能够精准地进行人数统计,为管理者提供重要参考信息。AI人数智能统计监测摄像头具有实时…

Android 中的卡顿丢帧原因概述 - 方法论

Android 手机使用中的卡顿问题 , 一般来说手机厂商和 App 开发商都会非常重视 , 所以不管是手机厂商还是 App 开发者 , 都会对卡顿问题非常重视 , 内部一般也会有专门的基础组或者优化组来进行优化 . 目前市面上有一些非常棒的第三方性能监控工具 , 比如腾讯的 Matrix ; 手机厂…

JavaScript的常用库 —— jQuery

利用JS去操控HTML和CSS,常用库之jQuery ฅʕ•̫͡•ʔฅjQuery用来更加方便地去控制前端的HTML标签和CSS属性。使用方式:1. 直接在<head>元素中添加: <script src="https://cdn.acwing.com/static/jquery/js/jquery-3.3.1.min.js"></script> 2…

2 FreeRTOS移植

2 FreeRTOS移植 2.1 源码基本认识获取源码。官网地址:FreeRTOS™ - FreeRTOS™ 源码内文件结构:1) FreeRTOS文件夹结构2) Source文件夹结构3) portable文件夹结构 portable文件夹里面有编译器、内核环境可以选择。其中keil是我们使用的编译器类型,但Keil文件夹里只有一个…

22蓝帽初赛

参考wp:http://mp.weixin.qq.com/s?__biz=Mzk0MTQzNjIyNg==&mid=2247487196&idx=1&sn=48094c5a78749b45c3598ed51a5df0e3&chksm=c3901b8acd56bc2d1d06b323e9d1e86b90048a35dc3b3301b60bb1f488a764f0b52ebc490113&mpshare=1&scene=23&srcid=01218…

【Azure APIM】APIM服务配置网络之后出现3443端口不通,Management Endpoint不健康状态

如果没有关联的网络安全组,则阻止所有网络流量通过子网和网络接口。问题描述 APIM服务在配置网络之后,查看网络状态发现Management Endpoint是不健康状态, 提示无法连接到3443端口。错误消息: Failed to connect to management endpoint at xxxxxxxx.management.azure-api.…

【模拟电子技术】11-放大电路的性能指标

【模拟电子技术】11-放大电路的性能指标通过输入,输出侧的各一个电容来到输入纯交流,输出纯交流Ui变化引起UBE变化,UBE变化引起IB变化,IB变化引起IC变化,IC变化引起UCE变化,UCE变化引起Uo变化关于输入,输出等效电路的问题: 输入电阻Ri越大越好还是越小越好?当然是越大…