You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取被装饰器包装后的原函数的参数名称?

获取被装饰函数的参数名称

当你用装饰器包装函数后,直接访问query_data其实拿到的是装饰器返回的包装器函数start_end_date_wrapper_args,所以query_data.__code__.co_varnames返回的是包装器的参数kwargs。要获取原函数query_data的参数,核心是先拿到被包装的原函数对象,下面提供两种可行方法:

方法一:手动给包装器添加原函数引用

修改你的装饰器,给包装器函数添加一个指向原函数的属性(比如标准约定的__wrapped__):

import datetime as dt

def start_end_date_wrapper_fn(function):
    def start_end_date_wrapper_args(**kwargs):
        kwargs = kwargs.copy()  # 仅在函数作用域内更新
        if kwargs.get('forecast_or_train') == 'forecast':
            kwargs['start_date'] = kwargs['start_date'] + dt.timedelta(days=-30)
            kwargs['end_date'] = kwargs['end_date'] + dt.timedelta(days=30)
            del kwargs['forecast_or_train']  # 修正原代码中的笔误(原写为train_or_forecast)
        return function(**kwargs)

    # 手动绑定原函数到包装器的__wrapped__属性
    start_end_date_wrapper_args.__wrapped__ = function
    return start_end_date_wrapper_args

@start_end_date_wrapper_fn
def query_data(start_date, end_date):
    # do something
    pass

之后就可以通过__wrapped__获取原函数,再提取参数:

# 方法1:用inspect模块(推荐,兼容复杂参数场景)
import inspect
original_func = query_data.__wrapped__
params = inspect.signature(original_func).parameters.keys()
print(list(params))  # 输出: ['start_date', 'end_date']

# 方法2:用__code__属性(仅适用于简单位置参数)
original_code = query_data.__wrapped__.__code__
print(original_code.co_varnames[:original_code.co_argcount])  # 输出: ('start_date', 'end_date')

方法二:使用functools.wraps(推荐标准做法)

Python标准库的functools.wraps专门用于保留被装饰函数的元数据,它会自动给包装器添加__wrapped__属性,同时同步原函数的__name__、__doc__等信息:

import datetime as dt
import functools

def start_end_date_wrapper_fn(function):
    @functools.wraps(function)  # 添加这一行即可
    def start_end_date_wrapper_args(**kwargs):
        kwargs = kwargs.copy()
        if kwargs.get('forecast_or_train') == 'forecast':
            kwargs['start_date'] = kwargs['start_date'] + dt.timedelta(days=-30)
            kwargs['end_date'] = kwargs['end_date'] + dt.timedelta(days=30)
            del kwargs['forecast_or_train']
        return function(**kwargs)

    return start_end_date_wrapper_args

@start_end_date_wrapper_fn
def query_data(start_date, end_date):
    # do something
    pass

获取参数的方式和方法一完全一致:

import inspect
sig = inspect.signature(query_data.__wrapped__)
print(list(sig.parameters.keys()))  # ['start_date', 'end_date']

补充说明

  • inspect.signature是更可靠的参数获取方式,能处理默认参数、可变参数(*args、**kwargs)等复杂场景;
  • __code__.co_varnames会包含函数内部的局部变量,所以需要配合co_argcount截取前N个元素才能得到位置参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:01:10