Python面试:装饰器的多种用法
Python面试:别只背八股文了,带你拆解装饰器的4种高阶实战用法
每次聊到Python面试,装饰器绝对是绕不开的“必考题”。很多候选人把闭包、高阶函数、@wraps背得滚瓜烂熟,但一到面试官问“你在实际项目里怎么用的”,就瞬间卡壳。今天咱们不扯干巴巴的理论,直接聊聊面试中如何把装饰器的多种用法讲出“实战味”,让面试官觉得你是真写过复杂业务的。
带参数的装饰器:从“套模板”到“懂嵌套”
别停留在无参装饰器了,面试时给个带参数的装饰器能瞬间拉开差距。比如写个控制重试次数的装饰器,这就好比给函数穿了件“防弹衣”,还能根据危险程度选择穿几层。
def retry(times=3):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for i in range(times):
try:
return func(*args, **kwargs)
except Exception as e:
if i == times - 1:
raise e
return wrapper
return decorator
面试加分点:跟面试官解释时,重点强调三层嵌套的逻辑。外层接收配置参数,中层接收被装饰函数,内层处理实际业务。这能证明你彻底搞懂了闭包的变量作用域,而不是只会抄网上的单模板。
权限与路由拦截:把装饰器用在“统一收口”
做Web开发(比如FastAPI或Flask),装饰器简直是权限校验的神器。别光在面试里写个打印“无权限”的假代码,要结合真实业务场景。
def require_role(role):
def decorator(func):
@wraps(func)
def wrapper(request, *args, **kwargs):
if request.user.role != role:
raise HTTPException(status_code=403, detail="权限不足")
return func(request, *args, **kwargs)
return wrapper
return decorator
面试加分点:告诉面试官,使用装饰器做拦截是为了避免业务代码里到处写 if not user.has_permission 的烂代码。把鉴权逻辑抽离到装饰器中,不仅让视图函数保持清爽,还方便后续统一修改鉴权规则,这就是典型的“单一职责原则”。
优雅的重试与降级:体现你的“工程思维”
网络请求、数据库连接偶尔会抽风,直接在业务代码里写 while 循环重试太丑了。这时候就需要一个专门处理异常的装饰器。
def retry_on_exception(exceptions=(Exception,), delay=1, backoff=2):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
current_delay = delay
while True:
try:
return func(*args, **kwargs)
except exceptions as e:
current_delay *= backoff
time.sleep(current_delay)
return wrapper
return decorator
面试加分点:聊这个场景时,顺便提一嘴指数退避(Exponential Backoff)机制。说明你不仅考虑了重试,还考虑了频繁重试可能压垮下游服务的问题。面试官听到这种细节,绝对会觉得你考虑问题很周全,具备成熟的工程思维。
自定义缓存机制:展现对“性能优化”的把控
大家都知道 functools.lru_cache,但面试时自己手写一个简易版缓存装饰器,杀伤力更大。
def simple_cache(func):
cache = {}
@wraps(func)
def wrapper(*args, **kwargs):
# 将参数转化为可哈希的字符串作为key
key = str(args) + str(sorted(kwargs.items()))
if key not in cache:
cache[key] = func(*args, **kwargs)
return cache[key]
return wrapper
面试加分点:告诉面试官,虽然官方库很好用,但手写能考察对 *args 和 **kwargs 的底层处理。重点指出字典的key必须是不可变类型,所以这里用字符串拼接来生成缓存键。如果能把 functools.wraps 保留原函数元数据(如 __name__ 和 __doc__)的细节讲清楚,这波面试基本就稳了。
结语
装饰器的本质,其实就是“开放封闭原则”在Python里的最佳实践——对扩展开放,对修改封闭。面试时,别把它当成一个孤立的语法点去死记硬背,而是把它当成你解决代码冗余、统一业务逻辑的“手术刀”。把这几个实战场景揉进你的回答里,面试官自然会觉得你是个有经验的“老手”。


还没有评论,来说两句吧...