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

Python导入模块时传递变量替代builtins实现跨文件装饰器调用

解决方案

你当前使用builtins注入全局对象的方式确实存在诸多问题:既污染全局命名空间,也没有类型提示支持,LSP自然会大量报错,且导入顺序出错就会直接触发运行时异常。以下方案完全保留你现有文件结构,不需要调整文件位置。

方案1:显式注册装饰器(最推荐,无LSP报错、完全符合Python规范)

这个方案只需要微调两个文件的代码,A.py完全不需要修改:

调整B.py代码

删除builtins导入,新增注册函数接收外部传入的装饰器:

def foo():
    print("foo")

def poo():
    print("poo")

# 新增注册方法,接收外部传入的实例装饰器
def register_decorator(decorator):
    global foo, poo
    # 批量替换已定义的函数为装饰后的版本
    foo = decorator(foo)
    poo = decorator(poo)

调整main.py代码

删除builtins相关逻辑,实例化后主动调用注册方法即可:

from mylib.A import A
import mylib.B as B

a = A("This is printing in the decorator")
# 传入实例的装饰器方法完成注册
B.register_decorator(a.our_decorator)

B.foo()
B.poo()

这个方案所有变量都是显式传递,类型可被LSP完全识别,不会有任何报错,也不存在全局污染的问题。

方案2:保留B.py的@装饰器写法

如果你习惯定义函数时用@语法标记需要装饰的函数,可以用延迟装饰的技巧,B.py代码调整如下:

# 临时装饰器,收集所有需要被装饰的函数
_decorate_list = []
def our_decorator(func):
    _decorate_list.append(func)
    return func

@our_decorator
def foo():
    print("foo")

@our_decorator
def poo():
    print("poo")

def register_decorator(real_decorator):
    for func in _decorate_list:
        # 批量替换为装饰后的函数
        globals()[func.__name__] = real_decorator(func)

main.py的用法和方案1完全一致,不需要修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:18:02