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

Python装饰器中如何获取被包装任意函数的父模块名称

获取被装饰函数所属模块名的实现方案

Python 函数对象原生自带__module__属性,不需要额外实现parent_module这类自定义属性,直接读取即可拿到函数定义所在的模块名。

核心用法

函数定义完成后,Python 会自动给函数对象绑定__module__属性,属性值为字符串类型,存储函数定义所在模块的全限定名:

  • 定义在根目录my_lib.py的函数,func.__module__值为my_lib
  • 定义在包路径pkg/utils.py的函数,func.__module__值为pkg.utils
  • 内置函数(比如print)的__module__值为builtins
  • 类中定义的方法,__module__值为类定义所在的模块名,完全覆盖日志、信息上报的使用场景

修正后的装饰器代码

你原来的代码存在两个问题:一是错误使用了不存在的parent_module属性,二是return func(*args, **kwargs)缩进错误,写到了wrapper函数外部,会导致装饰器加载时就直接执行被装饰函数,而非调用时触发逻辑。修正后可直接运行的代码如下:

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 直接读取原生__module__属性获取所属模块名
        print(f"Wrapping function {func.__name__} from module {func.__module__}")
        return func(*args, **kwargs)
    return wrapper

补充说明

  • 不推荐优先使用inspect.getmodule(func)方案:该方法会在运行时遍历sys.modules匹配所属模块,性能比直接读__module__差,且当函数所属模块未被加载到sys.modules时会返回None,稳定性不足
  • 如果确实需要拿到模块对象而非模块名字符串,可以通过sys.modules[func.__module__]获取,但要注意捕获KeyError异常,兼容极端场景下模块未加载的情况
  • 动态生成的函数、lambda表达式的__module__属性同样会自动绑定为定义位置所属模块,不需要额外处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:27:21