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

Python如何让高阶函数返回的函数在异常中显示指定的函数名

根因说明

你修改__name__属性不生效的核心原因是:Python触发参数不匹配这类和函数定义强相关的异常时,读取的是函数底层代码对象的__code__.co_name属性,而非开发者通常修改的__name__属性。functools.wraps默认只会复制__name__等表层元数据,不会修改代码对象内的名称值,因此异常信息里仍然会显示嵌套定义的new_func名称。

解决方案

Python 3.8及以上版本可以直接通过代码对象的replace方法修改co_name字段,实现异常信息中显示自定义名称的需求,完整实现如下:

from functools import wraps

def create_function(func, arguments: dict):
    @wraps(func)
    def new_func(x):
        return func(x, **arguments)
    # 修改代码对象的内置名称,让异常信息读取该值
    new_func.__code__ = new_func.__code__.replace(co_name=func.__name__)
    # 可选:修改全限定名,适配嵌套函数/类方法的场景
    new_func.__qualname__ = func.__qualname__
    return new_func

效果测试

调用测试代码:

f = create_function(sum, {})
print(f.__name__)
f()

输出结果完全符合预期:

sum
TypeError: sum() missing 1 required positional argument: 'x'

低版本Python兼容方案

如果你使用的是Python 3.8以下的版本,没有内置的code.replace方法,可以通过types.FunctionType手动构造新的函数对象实现相同效果:

from functools import wraps
import types

def create_function(func, arguments: dict):
    @wraps(func)
    def new_func(x):
        return func(x, **arguments)
    
    # 构造新的code对象,替换名称字段
    original_code = new_func.__code__
    new_code = types.CodeType(
        original_code.co_argcount,
        original_code.co_posonlyargcount,
        original_code.co_kwonlyargcount,
        original_code.co_nlocals,
        original_code.co_stacksize,
        original_code.co_flags,
        original_code.co_code,
        original_code.co_consts,
        original_code.co_names,
        original_code.co_varnames,
        original_code.co_filename,
        func.__name__, # 替换为原函数名
        original_code.co_firstlineno,
        original_code.co_lnotab,
        original_code.co_freevars,
        original_code.co_cellvars
    )
    new_func.__code__ = new_code
    new_func.__qualname__ = func.__qualname__
    return new_func

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:27:03