首页 > 编程语言 >Python基础之装饰器

Python基础之装饰器

时间:2023-09-18 23:22:46浏览次数:32  
标签:return Python args 基础 func kwargs 装饰 def

目录

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 ret
		return wrapper

d=Decorators()
@d.log_func
def fib(n):
	if n<=1:
		return 0
	return fib(n-1)+fib(n-2)

fib(3)

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

1.2.2 使用类方法装饰器

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

class Decorators:
	@classmethod
	def 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 ret
		return wrapper

@Decorators.log_func
def fib(n):
	if n<=1:
		return 0
	return fib(n-1)+fib(n-2)

fib(3)

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

1.2.3 使用类中静态装饰器

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

class Decorators:
	@staticmethod
	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 ret
		return wrapper

@Decorators.log_func
def fib(n):
	if n<=1:
		return 0
	return 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 ret
		return wrapper

	@log_func
	def fib(n):
		if n<=1:
			return 0
		return 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
    @property
    def x(self):
        return self._x

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

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

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

2 常用装饰器

2.1 @timer:测量执行时间

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

import time

def 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 result
	return 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] = result
		return result
	return wrapper
@memoize
def fibonacci(n):
	if n <= 1:
		return n
	return 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 here
		if 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 result

		return 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 None
		return 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 result
		else:
			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 time

def retry(max_attempts, delay):
	def decorator(func):
		def wrapper(*args, **kwargs):
			attempts = 0
			while attempts < max_attempts:
				try:
					return func(*args, **kwargs)
				except Exception as e:
					print(f"Attempt {attempts + 1} failed. Retrying in {delay} seconds.")
					attempts += 1
					time.sleep(delay)
			raise Exception("Max retry attempts exceeded.")
		return wrapper
	return 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 plt

def visualize_results(func):
	def wrapper(*args, **kwargs):
		result = func(*args, **kwargs)
		plt.figure()
		# Your visualization code here
		plt.show()
		return result
	return 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 warnings

def 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

标签:return,Python,args,基础,func,kwargs,装饰,def
From: https://www.cnblogs.com/jingzh/p/17713419.html

相关文章

  • 1:疯狂python讲义
    一:用户输入一个字符串和一个子串,程序打印出子串在字符串中出现的次数(从左到右),例如给定'abcdcdc'和'cdc',cdc出现2次a,b=input('请输入字符串:'),input('请输入字符子串:')a_len=len(a)b_len=len(b)count=0foriinrange(a_len):ifa[i:i+b_len]==b:count+=1print(......
  • 前端处理 File 的基础方法
    在前端开发过程中,处理File对象的场景还是蛮多的,熟练掌握对File对象的处理方法,可以极大提高前端工作的幸福度。JavaScript处理File对象的主要方式是通过HTML5的FileAPI。FileAPI提供了一组用于处理本地文件的API,包括创建、读取、写入和删除文件等操作。下面是一些常......
  • Python中捕获异常的方法及异常处理try-except-else-finally的区别
    在Python中,try、except、else和finally是我们常用的异常处理方式,有一个清晰的执行顺序很重要。在这篇攻略中,我们将详细探讨这些关键字的执行顺序,以便更有效地处理异常。先回顾一下这些关键字的含义和用途:try:执行可能会抛出异常的代码块;except:当try代码块中出现了异常,执行此代......
  • 【小沐学NLP】Python使用NLTK库的入门教程
    1、简介NLTK-自然语言工具包-是一套开源Python。支持自然研究和开发的模块、数据集和教程语言处理。NLTK需要Python版本3.7、3.8、3.9、3.10或3.11。NLTK是一个高效的Python构建的平台,用来处理人类自然语言数据。它提供了易于使用的接口,通过这些接口可以访问超过50个......
  • Python3 ACM模式的输入输出处理
    python3ACM模式的输入输出例子教学_amc模式python读取输入_汀、人工智能的博客-CSDN博客Python的输入是字符串,所以要自己转类型strip去掉左右两端的空白符,返回strslipt把字符串按空白符拆开,返回[str]map把list里面的值映射到指定类型,返回[type]EOF用抓异常print后面加逗号......
  • Python常用魔术方法汇总(20个魔法函数)
    本文将为您详细介绍Python中的让我们一起来了解这些特殊的函数,并提供一些在实际接口自动化工作中的示例代码。魔法函数(MagicMethods),也被称为特殊方法或双下划线方法,是Python中一些特殊命名的函数,它们以双下划线开头和结尾。这些函数定义了对象在特定情况下的行为,例如创建、比较、......
  • Python成员方法、类方法与静态方法的区别
    Python基础教程:3个方面理解Python的类方法与静态方法在Python语言中有如下3种方法:成员方法类方法(classmethod)静态方法(staticmethod)可能很多同学不清楚这3种方法,尤其是后两类方法到底有什么不同。为此,本文将对这3种方法做一次敲骨沥髓的深度剖析。先说一下这3种方法的差异,......
  • 1.MySQL、基础架构(SQL语句执行流程、更新语句执行流程)
    1.MySQL的索引有哪些索引在什么层面:索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。B+树索引:是大多数MySQL存储引擎的默认索引类型。哈希索引:哈希索引能以O(1)时间进行查找,但是失去了有序性;InnoDB存储引擎有一个特殊的功能叫......
  • [HUBUCTF 2022 新生赛]ezPython
    附件链接:https://wwvc.lanzouj.com/iIqq218z5x0d给了一个pyc文件利用命令将pyc转换为py文件uncompyle6ezPython.pyc>ezPython.py打开py文件#uncompyle6version3.9.0#Pythonbytecodeversionbase3.7.0(3394)#Decompiledfrom:Python3.8.2(tags/v3.8.2:7b3ab......
  • python学习计划
    首先我要去购买《Python编程,从入门到实践》这本书来学习python这门课程首先第一个月我要学习python的基础知识第一周:了解Python的基础,包括变量、数据类型、运算符和基本输入/输出。第二周:学习条件语句(if、elif、else)和循环(for、while)。第三周:掌握Python的函数和参数传递。第......