Python 装饰器:优雅地增强函数功能

Python 装饰器:优雅地增强函数功能

一、什么是装饰器?

装饰器 (Decorator) 是 Python 中的一种特性,允许你在 不修改原始函数代码 的情况下,为其加入新的功能或行为。

它的实质是:一个函数,接收另一个函数作为参数,返回一个新的函数。

二、最简单的装饰器

def my_decorator(func): 
	def wrapper():
    	print("函数开始执行")
        func()
        print("函数执行结束")
        return wrapper 
        
@my_decorator 
def say_hello():
	print("Hello, world!")

say_hello() 

三、带参数的装饰器

def log(message):
	def decorator(func):
    	def wrapper(*args, **kwargs): 
            print(f"[{message}] 函数开始") 
            result = func(*args, **kwargs) 
            print(f"[{message}] 函数结束") 
            return result 
            return wrapper 
            return decorator 
    	
@log("日志") 
def add(a, b): 
    return a + b 

add(3, 5) 

四、实际场景

  • 日志记录
  • 权限校验
  • 性能监控
  • 缓存 (如 functools.lru_cache)
  • Web 路由注册 (Flask, FastAPI)

五、functools.wraps

from functools import wraps 

def my_decorator(func): 
    @wraps(func) 
    def wrapper(*args, **kwargs): 
        print("开始") 
        return func(*args, **kwargs) 
    return wrapper

六、装饰器装饰类方法

装饰实例方法

def log(func): 
	def wrapper(self, *args, **kwargs): 
		print(f"[LOG] {func.__name__}") 
		return func(self, *args, **kwargs) 
		return wrapper 

class MyClass: 
	@log 
	def say_hello(self): 
		print("Hello from instance") 

装饰类方法

def log_classmethod(func): 
    def wrapper(cls, *args, **kwargs): 
        print(f"[CLASSLOG] {func.__name__}") 
        return func(cls, *args, **kwargs) 
        return wrapper 
	
class MyClass: 
	@classmethod 
	@log_classmethod 
	def do_something(cls): 
		print("Running...") 

装饰静态方法

def log_static(func): 
    def wrapper(*args, **kwargs): 
        print(f"[STATICLOG] {func.__name__}") 
        return func(*args, **kwargs)
    	return wrapper
   
class MyClass:
    @staticmethod
    @log_static
    def static_action(): 
        print("Static method") 

七、装饰器类 (Decorator Class)

基本示例

class MyDecorator: 
	def __init__(self, func):
    	self.func = func 
    
    def __call__(self, *args, **kwargs): 
    	print("开始") 
    	result = self.func(*args, **kwargs) 
    	print("结束") 
    	return result
        
    @MyDecorator
    def greet(name): 
    	print(f"Hello, {name}!") 

带状态的装饰器

class CallCounter: 
	def __init__(self, func): 
		self.func = func 
		self.count = 0 
		
	def __call__(self, *args, **kwargs): 
		self.count += 1 
		print(f"第 {self.count} 次调用") 
		return self.func(*args, **kwargs) 

带参数的装饰器类

class LogWithPrefix: 
    def __init__(self, prefix): 
        self.prefix = prefix 
    
    def __call__(self, func):
        def wrapper(*args, **kwargs):
            print(f"[{self.prefix}] 开始")
            result = func(*args, **kwargs)
            print(f"[{self.prefix}] 结束")
            return result
        return wrapper 

八、装饰器与异步编程

装饰 async 函数

import asyncio
import functools

def async_logger(func): 
	@functools.wraps(func) 
	async def wrapper(*args, **kwargs):
    	print(f"[ASYNC] {func.__name__} 开始")
        result = await func(*args, **kwargs)
        print(f"[ASYNC] {func.__name__} 结束")
        return result
     return wrapper
     
@async_logger
async def fetch_data():
	await asyncio.sleep(1)
	print("数据已获取")

asyncio.run(fetch_data()) 

通用装饰器:同时/异步全支持

import inspect 

def smart_logger(func): 
	if inspect.iscoroutinefunction(func): 
		async def async_wrapper(*args, **kwargs):
        	print("[ASYNC] 开始") 
        	result = await func(*args, **kwargs)
            	print("[ASYNC] 结束")
                return result
            return async_wrapper
    else: 
    	def sync_wrapper(*args, **kwargs):
        	print("[SYNC] 开始")
            result = func(*args, **kwargs)
            	print("[SYNC] 结束")
                return result
            return sync_wrapper 

九、思维导图

思维导图

小结

Python 装饰器是很强大的技术,不仅仅是代码优化的工具,更是让你的代码更 Pythonic 的重要手段。
无论是函数装饰器、方法装饰器、装饰器类、还是异步世界下的装饰器,都是 Python 高级技巧的核心组成部分。
如果你熟练装饰器,你不仅仅是在写代码,而是在写有结构、可重用、有风格的 Python 程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值