当前位置: 首页 > news >正文

Python装饰器:让函数更强大

在Python编程中,装饰器是一个强大的工具,它允许程序员以一种简洁优雅的方式修改或增强函数的行为,而无需更改其源代码。本文将介绍装饰器的基本概念、工作原理以及一些实际应用案例。
在这里插入图片描述

什么是装饰器?

装饰器本质上是一个接受函数作为参数的函数,并返回一个新的函数。这个新的函数通常会包含原函数的一些额外功能,比如日志记录、性能测试、事务处理、缓存、权限校验等。

装饰器的基本语法

一个简单的装饰器可以这样定义:

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

这里,my_decorator 是一个装饰器,它接受一个函数 func 作为参数,并返回一个新的函数 wrapper

使用装饰器

要使用上面定义的装饰器,我们可以这样做:

@my_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.

带参数的装饰器

有时候我们需要给装饰器传递参数来定制它的行为,例如设置日志级别:

def log(level):def decorator(func):def wrapper(*args, **kwargs):print(f"[{level}] The function {func.__name__} is about to be called.")result = func(*args, **kwargs)print(f"[{level}] The function {func.__name__} has been called.")return resultreturn wrapperreturn decorator@log("INFO")
def add(a, b):return a + bprint(add(10, 20))

这将输出:

[INFO] The function add is about to be called.
[INFO] The function add has been called.
30

实际应用案例

性能测试装饰器

一个常见的用途是在开发过程中进行性能测试。以下是一个简单的性能测试装饰器示例:

import timedef performance_test(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)end_time = time.time()print(f"{func.__name__} took {end_time - start_time:.6f} seconds to run.")return resultreturn wrapper@performance_test
def do_something_heavy():# Simulate some heavy computationtime.sleep(2)do_something_heavy()

缓存装饰器

另一个有用的应用是缓存结果,以减少重复计算的时间消耗:

cache = {}def memoize(func):def wrapper(*args):if args not in cache:cache[args] = func(*args)return cache[args]return wrapper@memoize
def fibonacci(n):if n < 2:return nelse:return fibonacci(n-1) + fibonacci(n-2)print(fibonacci(10))  # This will compute and cache the result
print(fibonacci(10))  # This will retrieve the cached result, much faster

结论

装饰器是Python中一个非常有用的特性,它可以帮助开发者以更加灵活和模块化的方式来组织代码。通过理解和掌握装饰器,你可以编写出更高效、更易于维护的程序。

相关文章:

  • java-享元模式
  • 从0到1,AI我来了- (3)AI图片识别的理论知识-I
  • 【Linux】从零开始认识多线程 --- 线程ID
  • .NET Core 发展历程和版本迭代
  • 人工蜂鸟算法(Artificial Hummingbird Algorithm,AHA)及其Python和MATLAB实现
  • HTML前端 盒模型及常见的布局 流式布局 弹性布局 网格布局
  • Linux下git入门操作
  • springboot在加了mapper之后报错
  • 第六章:支持向量机
  • 国科大作业考试资料-人工智能原理与算法-2024新编-第十二次作业整理
  • opencv 按键开启连续截图,并加载提示图片
  • 论文写作之latex配置(VSCODE+TEXT LIVE)
  • THS配置keepalive(yjm)
  • JAVA用TreeMap实现JSON按字母升序排序
  • MySQL中的DQL
  • 〔开发系列〕一次关于小程序开发的深度总结
  • Android 控件背景颜色处理
  • Angular Elements 及其运作原理
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • C++类的相互关联
  • JS专题之继承
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • SOFAMosn配置模型
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 程序员最讨厌的9句话,你可有补充?
  • 从零开始学习部署
  • 基于游标的分页接口实现
  • 开发基于以太坊智能合约的DApp
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • -- 数据结构 顺序表 --Java
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • ​ubuntu下安装kvm虚拟机
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (学习日记)2024.02.29:UCOSIII第二节
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • .Net Redis的秒杀Dome和异步执行
  • .Net 代码性能 - (1)
  • .net 调用海康SDK以及常见的坑解释
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .net 无限分类
  • .net经典笔试题
  • /var/lib/dpkg/lock 锁定问题
  • @Autowired和@Resource的区别
  • @FeignClient注解,fallback和fallbackFactory
  • @html.ActionLink的几种参数格式
  • [ 第一章] JavaScript 简史
  • [000-01-011].第2节:持久层方案的对比
  • [16/N]论得趣
  • [AI资讯·0612] AI测试高考物理题,最高准确率100%,OpenAI与苹果合作,将ChatGPT融入系统中,大模型在物理领域应用潜力显现
  • [Android] Implementation vs API dependency
  • [Delphi]一个功能完备的国密SM4类(TSM4)[20230329更新]
  • [Docker]十一.Docker Swarm集群raft算法,Docker Swarm Web管理工具