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

Python基础之装饰器

文章目录

  • 1 装饰器
    • 1.1 定义
    • 1.2 使用示例
      • 1.2.1 使用类中实例装饰器
      • 1.2.2 使用类方法装饰器
      • 1.2.3 使用类中静态装饰器
      • 1.2.4 使用类中普通装饰器
    • 1.3 内部装饰器
      • 1.3.1 @property
  • 2 常用装饰器
    • 2.1 @timer:测量执行时间
    • 2.2 @memoize:缓存结果
    • 2.3 @validate_input:数据验证
    • 2.4 @log_results:日志输出
    • 2.5 @suppress_errors:优雅的错误处理
    • 2.6 @validate_output:确保质量结果
    • 2.7 @retry:重试执行
    • 2.8 @visualize_results:漂亮的可视化
    • 2.9 @debug:调试变得更容易
    • 2.10 @deprecated:处理废弃的函数

1 装饰器

装饰器(Decorators)是Python中一种强大而灵活的功能,用于修改或增强函数或类的行为。

1.1 定义

装饰器本质上是一个函数,它接受另一个函数或类作为参数,并返回一个新的函数或类。它们通常用于在不修改原始代码的情况下添加额外的功能或功能
装饰器函数是一种Python语言中的特殊函数,它可以用来修改其他函数的行为。装饰器函数通常接受一个函数作为参数,并返回一个新的函数,这个新函数通常会在原函数的基础上添加一些额外的功能

作用:为函数增加新功能,减少重复性操作,使代码简洁

1.2 使用示例

使用装饰器的步骤:

  • 定义装饰器
  • 通过@调用装饰器

1.2.1 使用类中实例装饰器

装饰器一般是放在全局命名空间或单独一个类里,但是把装饰器放到类里面,相当于把一个函数变成类的方法

class Decorators:def log_func(self,func):def wrapper(*args,**kwargs):print(f"function start")print(f"args:{args}")ret=func(*args,**kwargs)print(f"function end!")return retreturn wrapperd=Decorators()
@d.log_func
def fib(n):if n<=1:return 0return fib(n-1)+fib(n-2)fib(3)

使用缺点:每次使用装饰器必须创建一个对象,且self参数没有用

1.2.2 使用类方法装饰器

不用实例中装饰器可以使用类中装饰器,添加@classmethod变成类方法

class Decorators:@classmethoddef log_func(cls,func):def wrapper(*args,**kwargs):print(f"function start")print(f"args:{args}")ret=func(*args,**kwargs)print(f"function end!")return retreturn wrapper@Decorators.log_func
def fib(n):if n<=1:return 0return fib(n-1)+fib(n-2)fib(3)

这种方式虽然不用创建对象了,直接类名调用,但是第一个参数cls依然没用到

1.2.3 使用类中静态装饰器

假如装饰器和对象无关,和类无关,可以使用静态装饰器@staticmethod

class Decorators:@staticmethoddef log_func(func):def wrapper(*args,**kwargs):print(f"function start")print(f"args:{args}")ret=func(*args,**kwargs)print(f"function end!")return retreturn wrapper@Decorators.log_func
def fib(n):if n<=1:return 0return fib(n-1)+fib(n-2)fib(3)

这种方式虽然不用创建对象,直接类名调用,也不会有第一个参数没用到的情况
当把一个装饰器封装到类里面时,这个方式就不错
注意:用@staticmethod修饰的装饰器不能装饰类里面的方法,会直接报错

1.2.4 使用类中普通装饰器

如果在含有装饰器的类中使用自己的装饰器时,可以把装饰器当成普通方法

class Decorators:	# 此处的log_func可以理解为辅助函数或辅助装饰器def log_func(func):def wrapper(*args,**kwargs):print(f"function start")print(f"args:{args}")ret=func(*args,**kwargs)print(f"function end!")return retreturn wrapper@log_funcdef fib(n):if n<=1:return 0return fib(n-1)+fib(n-2)# 在类中或类外都可以使用装饰器添加如下方法# 这句话只能放到类末尾log_func=staticmethod(log_func)
d=Decorators()
d.fib(3)

如上代码,就可以在类中或者类外都使用装饰器

1.3 内部装饰器

1.3.1 @property

@propertyPython中的一个内置装饰器,它可以将一个方法转换为属性。具体来说,@property 装饰器可以将一个方法转换为只读属性,这意味着我们可以像访问属性一样访问这个方法,而不需要调用它。例如:

class MyClass:def __init__(self, x):self._x = x@propertydef x(self):return self._x

在这个例子中,我们定义了一个名为 MyClass 的类,并在其中定义了一个名为 x 的方法。我们使用 @property 装饰器将该方法转换为只读属性,这样我们就可以像访问属性一样访问这个方法

obj = MyClass(42)print(obj.x)  # 输出 42

即:带有@property装饰器的函数被调用时,后面不能加小括号()

2 常用装饰器

2.1 @timer:测量执行时间

优化代码性能是非常重要的。@timer装饰器可以帮助我们跟踪特定函数的执行时间。通过用这个装饰器包装函数,我可以快速识别瓶颈并优化代码的关键部分。下面是它的工作原理:

import timedef timer(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:.2f} seconds to execute.")return resultreturn wrapper
@timer
def my_data_processing_function():
# Your data processing code here

将@timer与其他装饰器结合使用,可以全面地分析代码的性能。

2.2 @memoize:缓存结果

在数据科学中,我们经常使用计算成本很高的函数。@memoize装饰器帮助我缓存函数结果,避免了相同输入的冗余计算,显著加快工作流程:

def memoize(func):cache = {}def wrapper(*args):if args in cache:return cache[args]result = func(*args)cache[args] = resultreturn resultreturn wrapper
@memoize
def fibonacci(n):if n <= 1:return nreturn fibonacci(n - 1) + fibonacci(n - 2)

在递归函数中也可以使用 @memoize来优化重复计算。

2.3 @validate_input:数据验证

数据完整性至关重要, @validate_input 装饰器可以验证函数参数,确保它们在继续计算之前符合特定的标准:

def validate_input(func):def wrapper(*args, **kwargs):# Your data validation logic hereif valid_data:return func(*args, **kwargs)else:raise ValueError("Invalid data. Please check your inputs.")return wrapper
@validate_input
def analyze_data(data):
# Your data analysis code here

可以方便的使用@validate_input在数据科学项目中一致地实现数据验证。

2.4 @log_results:日志输出

在运行复杂的数据分析时,跟踪每个函数的输出变得至关重要。@log_results装饰器可以帮助我们记录函数的结果,以便于调试和监控:

def log_results(func):def wrapper(*args, **kwargs):result = func(*args, **kwargs)with open("results.log", "a") as log_file:log_file.write(f"{func.__name__} - Result: {result}\n")return resultreturn wrapper
@log_results
def calculate_metrics(data):
# Your metric calculation code here

@log_results与日志库结合使用,以获得更高级的日志功能。

2.5 @suppress_errors:优雅的错误处理

数据科学项目经常会遇到意想不到的错误,可能会破坏整个计算流程。@suppress_errors装饰器可以优雅地处理异常并继续执行:

def suppress_errors(func):def wrapper(*args, **kwargs):try:return func(*args, **kwargs)except Exception as e:print(f"Error in {func.__name__}: {e}")return Nonereturn wrapper
@suppress_errors
def preprocess_data(data):
# Your data preprocessing code here

@suppress_errors可以避免隐藏严重错误,还可以进行错误的详细输出,便于调试

2.6 @validate_output:确保质量结果

确保数据分析的质量至关重要。@validate_output装饰器可以帮助我们验证函数的输出,确保它在进一步处理之前符合特定的标准:

def validate_output(func):def wrapper(*args, **kwargs):result = func(*args, **kwargs)if valid_output(result):return resultelse:raise ValueError("Invalid output. Please check your function logic.")return wrapper@validate_output
def clean_data(data):
# Your data cleaning code here

这样可以始终为验证函数输出定义明确的标准。

2.7 @retry:重试执行

@retry装饰器帮助我在遇到异常时重试函数执行,确保更大的弹性:

import timedef retry(max_attempts, delay):def decorator(func):def wrapper(*args, **kwargs):attempts = 0while attempts < max_attempts:try:return func(*args, **kwargs)except Exception as e:print(f"Attempt {attempts + 1} failed. Retrying in {delay} seconds.")attempts += 1time.sleep(delay)raise Exception("Max retry attempts exceeded.")return wrapperreturn decorator@retry(max_attempts=3, delay=2)
def fetch_data_from_api(api_url):
# Your API data fetching code here

使用@retry时应避免过多的重试。

2.8 @visualize_results:漂亮的可视化

@visualize_results装饰器数据分析中自动生成漂亮的可视化结果

import matplotlib.pyplot as pltdef visualize_results(func):def wrapper(*args, **kwargs):result = func(*args, **kwargs)plt.figure()# Your visualization code hereplt.show()return resultreturn wrapper@visualize_results
def analyze_and_visualize(data):
# Your combined analysis and visualization code here

2.9 @debug:调试变得更容易

调试复杂的代码可能非常耗时。@debug装饰器可以打印函数的输入参数和它们的值,以便于调试:

def debug(func):def wrapper(*args, **kwargs):print(f"Debugging {func.__name__} - args: {args}, kwargs: {kwargs}")return func(*args, **kwargs)return wrapper
@debug
def complex_data_processing(data, threshold=0.5):
# Your complex data processing code here

2.10 @deprecated:处理废弃的函数

随着我们的项目更新迭代,一些函数可能会过时。@deprecated装饰器可以在一个函数不再被推荐时通知用户:

import warningsdef deprecated(func):def wrapper(*args, **kwargs):warnings.warn(f"{func.__name__} is deprecated and will be removed in future versions.", DeprecationWarning)return func(*args, **kwargs)return wrapper
@deprecated
def old_data_processing(data):
# Your old data processing code here

相关文章:

Python基础之装饰器

文章目录 1 装饰器1.1 定义1.2 使用示例1.2.1 使用类中实例装饰器1.2.2 使用类方法装饰器1.2.3 使用类中静态装饰器1.2.4 使用类中普通装饰器 1.3 内部装饰器1.3.1 property 2 常用装饰器2.1 timer:测量执行时间2.2 memoize:缓存结果2.3 validate_input:数据验证2.4 log_result…...

IDEA设置Maven 镜像

第一步&#xff1a;右键项目&#xff0c;选择Maven->Create ‘settings.xml’ 已经存在的话是Open ‘settings.xml’&#xff1a; 第二步&#xff1a;在settings.xml文件中增加阿里云镜像地址&#xff0c;代码如下&#xff1a; <?xml version"1.0" encodin…...

项目评定等级L1、L2、L3、L4

软件项目评定等级的数量可以因不同的评定体系和标准而异。一般情况下&#xff0c;项目评定等级通常按照项目的规模、复杂性和风险等因素来划分&#xff0c;可以有多个等级&#xff0c;常见的包括&#xff1a; L1&#xff08;Level 1&#xff09;&#xff1a;通常表示较小规模、…...

一个基于SpringBoot+Vue前后端分离学生宿舍管理系统详细设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…...

工作相关----《配置bond》

进入到/etc/sysconfig/network-scripts&#xff0c;按照要求配置主备关系 vim ifcfg-bond0&#xff0c;编写主要内容如下&#xff1a; /*mode1 表示主备份策略&#xff0c;miimon100 系统每100毫秒监测一次链路连接状态&#xff0c; 如果有一条线路不通就转入另一条线路*/ BOND…...

Nacos、ZooKeeper和Dubbo的区别

Nacos、ZooKeeper和Dubbo是三个不同的分布式系统组件&#xff0c;它们之间有以下几点区别&#xff1a; 功能定位&#xff1a;Nacos主要提供服务发现、配置管理和服务治理等功能&#xff0c;而ZooKeeper主要是分布式协调服务&#xff0c;提供了分布式锁、分布式队列等原语&#…...

刷一下算法

记录下自己的思路与能理解的解法,可能并不是最优解法,不定期持续更新~ 1.盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容…...

three.js——GUI的使用

GUI的使用 效果图1、导入gui2、创建一个GUI对象3、通过gui调用方法 name:按钮的名称 效果图 1、导入gui // 导入ligui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js2、创建一个GUI对象 const gui new GUI()3、通过gui调用方法 name:按钮的名称 // 创…...

LeetCode 332. Reconstruct Itinerary【欧拉回路,通路,DFS】困难

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

236. 二叉树的最近公共祖先 Python

文章目录 一、题目描述示例 1示例 2示例 3 二、代码三、解题思路 一、题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满…...

WPF中DataGrid控件绑定数据源

步骤 创建数据源&#xff1a;首先&#xff0c;我们需要创建一个数据源&#xff0c;可以是一个集合&#xff08;如List、ObservableCollection等&#xff09;&#xff0c;也可以是一个DataTable对象。数据源中的每个元素代表一行数据。 设置DataGrid的ItemsSource属性&#xff…...

Linux arm64 set_memory_ro/rw函数

文章目录 一、函数简介1.1 简介1.2 change_memory_common1.3 __change_memory_common 二、apply_to_page_range函数2.1 apply_to_page_range2.2 apply_to_p4d_range2.3 apply_to_pud_range2.4 apply_to_pmd_range2.5 apply_to_pte_range 三、hook系统调用参考资料 一、函数简介…...

安达发|APS排单软件中甘特图的应用

近几年来&#xff0c;企业对生产效率和管理水平的要求越来越高。为了提高生产效率&#xff0c;降低生产成本&#xff0c;许多企业开始引入先进的生产计划与调度系统&#xff08;APS&#xff09;&#xff0c;实现生产过程的自动化、智能化管理。APS排产软件是一种能够根据企业的…...

快速上手Linux基础开发工具

目录 软件包管理器 概念理解 用法示例 - 以yum为例 vim 模式的切换 常用操作 插件和配置 gcc/g gdb make / makefile 软件包管理器 概念理解 在Linux下安装软件的话&#xff0c;一个比较原始的办法是下载程序的源代码&#xff0c;然后进行编译&#xff0c;进而得到…...

【开发工具】idea 的全局搜索快捷键(Ctrl+shift+F)失效

文章目录 前言1. 取消 输入法的快捷键&#xff08;推荐使用&#xff09;2.更改 idea的快捷键3. 热键占用总结 前言 当你发现在idea 中看到用于全局搜索的快捷键就是 CtrlshiftF&#xff0c;可是怎么按都不管用的时候&#xff0c;你就不要再执着于自己的操作继续狂点电脑按键了…...

港联证券:“火箭蛋”来袭 蛋价涨势能否延续?

上个交易周&#xff08;9月11日至15日&#xff09;&#xff0c;鸡蛋期货商场呈现了意想不到的涨势。9月15日&#xff0c;鸡蛋期货多个合约大涨&#xff0c;其中2310合约涨超5.6%&#xff0c;主力合约2311盘中两度触及涨停&#xff0c;最终收涨6%。业内人士以为&#xff0c;鸡蛋…...

Vue3_vite

使用Vue-cli创建 使用vite创建 Composition API 组合API setup 1.Vue3中的一个新的配置项,值为一个函数 2.可以将组件中所用到的数据,方法等配置在setup中. 3.setup函数的两种返回值 3.1若返回一个对象,则对象中的属性,方法,在模板中均可以直接使用. 3.2若返回一个渲染函数…...

python-字符串去掉空格的常见方法

python提供了去掉字符串空格的方法&#xff0c;可以满足大部分需求。 但在实际应用中&#xff0c;还需要灵活借助python其他方法&#xff0c;来实现字符串空格的删除。 比如&#xff0c;去掉字符串的全部空格、字符串连续空格保留一个等&#xff0c;都需要结合其他的方法来实现…...

如何写出一个成熟的线上线下结合的营销方案?

分享一下咱们案例库里策划的一个线上线下结合的活动的案例。 这个活动是为了推广一个新品牌&#xff0c;增加品牌知名度和用户粘性。 你可以根据以下几个要点来进行活动策划&#xff1a; 1、目标&#xff1a; 让目标用户了解并喜欢新品牌&#xff0c;激发用户参与和分享&am…...

Vc - Qt - “扩张“的窗口

该示例演示了一个"扩张的窗口"&#xff0c;主窗口的布局为水平布局&#xff0c;内置两个子窗口&#xff0c;采用定时器设置左边窗口的宽度&#xff0c;达到控制"扩张"的目的。 #include <QApplication> #include <QWidget> #include <QHBox…...

vue学习-02vue入门之组件

删除Vue-cli预设 在用户根目录下(C:\Users\你的用户名)这个地址里有一个.vuerc 文件,修改或删除配置 组件 Props(组件之间的数据传递) Prop 的大小写 (camelCase vs kebab-case)不敏感Prop 类型: String Number Boolean Array Object Date Function Symbol传递静态或动态 Pr…...

解决Pycharm使用Conda激活环境失败的问题

Q:公司电脑终端使用powershell来激活conda环境时报错? 同时手动打开powershell报"profile.ps1” 无法被加载的错误 A: 1,手动打开powershell&#xff0c;设置管理员打开 2,打开powershell 打开 PowerShell 终端&#xff0c;并输入以下命令&#xff1a;Get-ExecutionPo…...

SpringSecurity 核心组件

文章目录 SpringSecurity 结构组件&#xff1a;SecurityContextHolder组件&#xff1a;Authentication组件&#xff1a;UserDetailsService组件&#xff1a;GrantedAuthority组件总结 SpringSecurity 结构 在SpringSecurity中的jar分为4个&#xff0c;作用分别为 jar作用spri…...

【Vue】快速入门和生命周期

目录 前言 一、vue的介绍 1. Vue.js是什么&#xff1f; 2. 库和框架的区别 3.基本概念和用法&#xff1a; 二、MVVM的介绍 1. 什么是MVVM&#xff1f; 2. MVVM的组成部分 3. MVVM的工作流程 4. MVVM的优势 5. MVVM的应用场景 三、vue实例 1.模板语法&#xff1a; …...

JVM架构和内存管理优化

Java虚拟机&#xff08;JVM&#xff09;是Java编程语言的核心组件&#xff0c;负责执行Java字节码并提供运行时环境&#xff0c;使得Java程序可以在不同的平台上运行。了解JVM的工作原理和内存管理对于优化代码性能和理解Java的内存管理和垃圾收集机制非常重要。在本文中&#…...

C语言——贪吃蛇小游戏

目录 一、ncurse 1.1 为什么需要用ncurse&#xff1a; 1.2 ncurse的输入输出&#xff1a; 1.2.1 如何使用ncurse&#xff1a; 1.2.2 编译ncurse的程序&#xff1a; 1.2.3 测试输入一个按键ncurse的响应速度&#xff1a; 1.3 ncurse上下左右键获取&#xff1a; 1.3.1 如…...

PHP8中获取并删除数组中第一个元素-PHP8知识详解

我在上一节关于数组的教程&#xff0c;讲的是在php8中获取并删除数组中最后一个元素&#xff0c;今天分享的是相反的&#xff1a;PHP8中获取并删除数组中第一个元素。 回顾一下昨天的知识&#xff0c;array_pop()函数将返回数组的最后一个元素&#xff0c;今天学习的是使用arr…...

EtherCAT 总线型 4 轴电机控制卡解决方案

 技术特点  支持标准 100M/s 带宽全双工 EtherCAT 总线网络接口及 CoE 通信协议一 进一出&#xff08;RJ45 接口&#xff09;&#xff0c;支持多组动态 PDO 分组和对象字典的自动映射&#xff0c;支持站 号 ID 的自动设置与保存&#xff0c;支持 SDO 的电机参数设置与…...

Upload-labs十六和十七关

目录 第十六关第十七关 第十六关 直接上传php文件判断限制方式&#xff1a; 同第十五关白名单限制 第十六关源码&#xff1a; 代码逻辑判断了后缀名、content-type&#xff0c;以及利用imagecreatefromgif判断是否为gif图片&#xff0c;最后再做了一次二次渲染 第71行检测…...

软件包的管理

概念 在早期Linux系统中&#xff0c;要想在Linux系统中安装软件只能采取编译源码包的方式进行安装&#xff0c;所以早期安装软件是一件非常困难、耗费耐心的事情&#xff0c;而且大多数服务程序仅提供源代码&#xff0c;还需要运维人员编译后自行解决软件之间的依赖关系。所以…...

做刀模网站/娱乐热搜榜今日排名

衡量模型是否成功是什么使项目成功&#xff1f; 瀑布项目管理告诉我们&#xff0c;这与满足范围&#xff0c;时间和成本目标有关。 这些成功指标是否也适用于敏捷项目&#xff1f; 让我们来看看。 在敏捷项目中&#xff0c;我们一直在学习新信息。 范围可能会随时间变化&am…...

网站工信部备案流程/网站优化排名公司

我是LBJ&#xff1a;作为一名金融数据生产线的民工&#xff0c;我是如何拿到了电商行业的offer&#xff1f;首先&#xff0c;整个过程需要有主观能动性&#xff0c;也就是需要自己感兴趣&#xff0c;主动是第一前提。最开始我是被Python吸引到的&#xff0c;当时隐隐有点往程序…...

大连手机网站建设/甘肃seo网站

现在的单处理器系统使用指令级的并行机制&#xff08;ILP&#xff09;在执行流水线的不同硬件功能中同时执行多条指令。现在的共享内存多处理器系统使用ILP机制&#xff0c;但是还可以利用线程级的并行机制&#xff08;TLP&#xff09;。TLP不仅可以允许并行执行指令&#xff0…...

免费微信小程序制作/百度seo流量

链表05--复杂链表的复制-jz25题目概述解析&参考答案注意事项说明题目概述 算法说明 输入一个复杂链表&#xff08;每个节点中有节点值&#xff0c;以及两个指针&#xff0c;一个指向下一个节点&#xff0c;另一个特殊指针random指向一个随机节点&#xff09;&#xff0c;请…...

延吉做网站/常见的网络营销方式有哪几种

输出浮点数自动忽略后面多余0的方法 很多小伙伴在使用%f来输出浮点数时&#xff0c;后面会跟着多余的0&#xff0c;有的题目会要求自动省略后面的0&#xff0c;下面就来提供一种方法来自动省略浮点数后多余的0的方法。 我们可以使用%g来输出浮点数。看下面这段代码&#xff1a…...

安徽省经工建设集团网站/郑州seo优化

一、时间函数 在使用存储过程&#xff0c;sql函数的时候&#xff0c;会遇到一些对时间的处理。比如时间的获取与加减。这里就用到了sql自带的时间函数。下面我列出这些函数&#xff0c;方便日后记忆&#xff0c;使用。 --getdate 获取当前时间select getdate()--dateadd 原有时…...