You need to enable JavaScript to run this app. 如何实现可向被装饰函数传递可选关键字参数的Python装饰器
优惠活动
大模型
产品
解决方案
定价
更多

如何实现可向被装饰函数传递可选关键字参数的Python装饰器

Python 可选参数传递装饰器实现方案

原有捕捉 TypeError 的实现存在明显缺陷:

  • 会误拦截函数内部抛出的 TypeError 异常
  • 依赖异常信息字符串匹配,不同语言环境、Python版本的异常提示存在差异,兼容性差

最优实现思路

使用 Python 标准库的 inspect 模块检测被装饰函数的参数签名,判断函数是否支持接收目标关键字参数,再决定是否传入参数。

基础实现代码

import inspect
from functools import wraps

def mydecorator(fn):
    @wraps(fn) # 保留原函数的元信息(函数名、文档字符串等)
    def wrapper(*args, **kwargs):
        # 定义要传递的可选关键字参数,可根据需求修改
        optional_params = {"magic_word": "Abracadabra!"}
        # 获取被装饰函数的参数签名
        sig = inspect.signature(fn)
        func_params = sig.parameters

        # 筛选出函数可接收的参数
        pass_params = {}
        for k, v in optional_params.items():
            # 两种情况可以传参数:1.函数显式定义了该参数 2.函数定义了**kwargs接收任意关键字参数
            if k in func_params or any(p.kind == inspect.Parameter.VAR_KEYWORD for p in func_params.values()):
                pass_params[k] = v
        
        # 合并参数,调用方传入的kwargs优先级更高
        final_kwargs = {**pass_params, **kwargs}
        return fn(*args, **final_kwargs)
    return wrapper

测试效果

@mydecorator
def dummy_without_magic_word():
    print('hello world')

@mydecorator
def dummy_with_magic_word(magic_word):
    print(magic_word)

dummy_without_magic_word() # 输出:hello world
dummy_with_magic_word() # 输出:Abracadabra!

扩展灵活版本

如果需要在装饰器使用时动态指定要传递的可选参数,可以嵌套一层实现参数化装饰器:

import inspect
from functools import wraps

def mydecorator(**optional_params):
    def decorator(fn):
        @wraps(fn)
        def wrapper(*args, **kwargs):
            sig = inspect.signature(fn)
            func_params = sig.parameters
            pass_params = {}
            for k, v in optional_params.items():
                if k in func_params or any(p.kind == inspect.Parameter.VAR_KEYWORD for p in func_params.values()):
                    pass_params[k] = v
            final_kwargs = {**pass_params, **kwargs}
            return fn(*args, **final_kwargs)
        return wrapper
    return decorator

扩展版本使用示例

# 装饰时指定要传入的参数值
@mydecorator(magic_word="Hocus Pocus!", other_param=123)
def dummy_with_magic_word(magic_word):
    print(magic_word)

dummy_with_magic_word() # 输出:Hocus Pocus!

内容的提问来源于stack exchange,提问作者theahura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 11:15:09