当前位置:首页>python>Python装饰器:让你代码优雅到尖叫,打工人们都学疯了!

Python装饰器:让你代码优雅到尖叫,打工人们都学疯了!

  • 2026-10-11 07:42:19
Python装饰器:让你代码优雅到尖叫,打工人们都学疯了!

还在重复造轮子?这个语法让你的代码高级10倍

各位编程界的老铁们好啊。

今天要聊的这个玩意儿,叫装饰器。

听到这仨字你是不是已经头疼了。什么@classmethod、@property、@abstractmethod,满屏的@符号看着就让人犯困。

别怕。看完这篇文章,保证你不仅看懂,还能自己写。

先从为什么需要装饰器说起

想象这么个场景——你有10个函数,领导让你加个功能:每个函数执行前打印日志、记录执行时间、异常了发个告警。

你会怎么做。改10个函数。太蠢了。

装饰器就是来解决这个问题的——在不修改原函数的情况下,给函数加点额外的功能。

最简单的装饰器,只需要5行

defmy_decorator(func):
defwrapper(*args, **kwargs):
        print("函数开始执行啦")
        result = func(*args, **kwargs)
        print("函数执行完啦")
return result
return wrapper

@my_decorator
defsay_hello(name):
    print(f"Hello {name}!")

say_hello("混子哥")

输出:

函数开始执行啦
Hello 混子哥!
函数执行完啦

看到没。加上@my_decorator这一行,原函数什么都没变,但多了打印功能。

带参数的装饰器,才是真正的王者

基础版本太简单了,来看看怎么给装饰器本身传参数。

import time

deftimer(timeout=0):
defdecorator(func):
defwrapper(*args, **kwargs):
            start = time.time()
            result = func(*args, **kwargs)
            elapsed = time.time() - start
if elapsed > timeout:
                print(f"函数执行了 {elapsed:.2f} 秒,超过阈值 {timeout} 秒")
else:
                print(f"函数执行了 {elapsed:.2f} 秒")
return result
return wrapper
return decorator

@timer(timeout=1)
defslow_function():
    time.sleep(2)
return"done"

@timer(timeout=5)
deffast_function():
return"quick!"

slow_function()
fast_function()

输出:

函数执行了 2.00 秒,超过阈值 1 秒
函数执行了 0.00 秒

这个@timer(timeout=1)就是带参数的装饰器,比@timer高级多了。

多个装饰器叠加,效果太骚了

deflog(func):
defwrapper(*args, **kwargs):
        print(f"[LOG] 调用 {func.__name__}")
return func(*args, **kwargs)
return wrapper

defuppercase(func):
defwrapper(*args, **kwargs):
        result = func(*args, **kwargs)
return result.upper() if isinstance(result, str) else result
return wrapper

@log
@uppercase
defgreet(name):
returnf"hello {name}"

print(greet("tom"))

输出:

[LOG] 调用 wrapper
HELLO TOM

装饰器执行顺序是从下往上的,所以实际顺序是:greet → uppercase → log。

类装饰器,了解一下?

函数装饰器玩腻了。来试试类装饰器。

classCountCalls:
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)

@CountCalls
deffibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)

fibonacci(5)
fibonacci(10)
fibonacci(5)

输出:

函数被调用了 1 次
函数被调用了 2 次
函数被调用了 3 次

实战场景来了,用装饰器简化Flask路由

from functools import wraps
from flask import request, jsonify

defvalidate_json(required_fields):
defdecorator(func):
        @wraps(func)
defwrapper(*args, **kwargs):
ifnot request.is_json:
return jsonify({"error": "需要JSON数据"}), 400

            data = request.get_json()
            missing = [f for f in required_fields if f notin data]
if missing:
return jsonify({"error": f"缺少字段: {missing}"}), 400

return func(*args, **kwargs)
return wrapper
return decorator

@app.route('/user', methods=['POST'])
@validate_json(['name', 'email'])
defcreate_user():
return jsonify({"message": "用户创建成功"})

看,用装饰器处理参数验证,代码清爽多了。

混子哥的个人观点

说实话,装饰器这玩意儿看着吓人,用起来是真香。

一定要掌握的场景:

  • 日志记录
  • 性能计时
  • 权限校验
  • 缓存结果
  • 重试机制

别乱用的场景:

  • 逻辑太复杂的装饰器,维护成本高
  • 嵌套太多层,调试会疯掉的

常见标准库装饰器,你肯定见过

# property - 把方法变成属性
classUser:
    @property
defname(self):
return self._name

# staticmethod - 静态方法
classMath:
    @staticmethod
defadd(a, b):
return a + b

# classmethod - 类方法
classPerson:
    @classmethod
deffrom_dict(cls, data):
return cls(**data)

# functools.lru_cache - 自动缓存
from functools import lru_cache

@lru_cache(maxsize=128)
defexpensive_calc(n):
return sum(range(n))

总结时间

装饰器类型
写法
使用场景
基本装饰器
@decorator
单一功能增强
带参装饰器
@decorator(args)
可配置的增强
类装饰器
@MyDecorator
需要保存状态的场景
多装饰器
@a @b
功能组合

记住:装饰器就是包装原函数,在不改变原函数的前提下添加新功能。搞懂这个,装饰器就没什么神秘的了。

最新文章

随机文章