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

如何访问传递给Python被装饰函数的args参数中的单个参数fname

问题分析与解决方法

你的实现思路整体正确,问题出在没有从装饰器接收的参数中提取fname变量:fname是被装饰函数的形参,不会自动在wrapper的作用域中生成,需要你手动从传入的位置参数args、关键字参数kwargs中提取对应值。

基础修复方案

因为你所有被装饰函数的第一个参数均为fname,可以直接优先取位置参数的第一个元素,为空时再从关键字参数中查找,适配位置传参和关键字传参两种调用方式:

def mydeco(func):
    def wrapper(*args, **kwargs):
        print(args)
        # 提取fname参数
        if args:
            fname = args[0]
        else:
            fname = kwargs.get("fname")
        if not fname:
            raise ValueError("被装饰函数必须传入fname参数")
               
        try:
            print('Before func')
            answer = func(*args,**kwargs)
            print('after func in wrapper')
            if answer == 2:
                print(f"Great job {fname}")
        except Exception as e:
            print('blah', e)
    
    return wrapper


@mydeco
def long(fname, lname):
    print(f"hello {fname} {lname}")
    return 2

@mydeco
def short(fname):
    print(f"hello {fname}")


short('Bob')
long('Bob', 'Smith')

运行后可正常输出预期内容:

('Bob',)
Before func
hello Bob
after func in wrapper
Great job Bob
('Bob', 'Smith')
Before func
hello Bob Smith
after func in wrapper
Great job Bob

进阶兼容方案

如果后续被装饰函数的参数顺序可能调整,fname不一定在第一位,可以用Python标准库inspect模块做参数绑定,不管fname在参数列表的哪个位置都能正确提取:

import inspect
def mydeco(func):
    def wrapper(*args, **kwargs):
        print(args)
        # 绑定参数到函数形参,自动匹配位置、关键字参数
        sig = inspect.signature(func)
        bound_args = sig.bind(*args, **kwargs)
        bound_args.apply_defaults()
        fname = bound_args.arguments["fname"]
               
        try:
            print('Before func')
            answer = func(*args,**kwargs)
            print('after func in wrapper')
            if answer == 2:
                print(f"Great job {fname}")
        except Exception as e:
            print('blah', e)
    
    return wrapper

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 02:27:03