如何实现Python包跨模块共享命名空间vars并支持交互tab补全
问题根源
- 你在
MyPackage/__init__.py中定义的vars是包级别的全局变量,start.py、tree.py两个模块没有显式导入的话,无法直接访问该变量,直接调用vars.update()会触发NameError - 就算取消
start.py中vars = globals()的注释,此时的vars是start.py模块自身的全局命名空间,和包级别的vars是完全独立的两个对象,自然无法同步其他模块生成的对象 - 额外提示:不要用
vars作为自定义变量名,会覆盖Python内置的vars()函数,容易引发不可预期的错误,建议重命名为shared_ns这类不会冲突的名称
修复方案
1. 修改__init__.py
# 全局共享命名空间,所有需要同步到交互环境的对象都需要更新到该变量 shared_ns = globals()
2. 修改tree.py
# 先导入包级别的共享命名空间 from MyPackage import shared_ns class Tree: B = 2 # 将当前模块定义的对象同步到共享命名空间 shared_ns.update(locals())
3. 修改start.py
import rlcompleter import readline import code # 先导入包级别的共享命名空间 from MyPackage import shared_ns from tree import Tree # 同步当前模块已定义的变量 shared_ns.update(locals()) class root: pass root = root() A = Tree() # 同步后续新增的对象 shared_ns.update({ "root": root, "A": A }) readline.set_completer(rlcompleter.Completer(shared_ns).complete) readline.parse_and_bind("tab: complete") code.InteractiveConsole(shared_ns).interact(banner="",exitmsg="Good Bye!")
注意事项
- 所有需要将内部对象同步到交互提示符的模块,都要先导入包级别的
shared_ns,定义完目标对象后调用shared_ns.update(locals())完成同步 - 如果后续有动态生成的对象需要加入补全,只要执行
shared_ns.update({"对象名": 对象实例})即可生效
内容的提问来源于stack exchange,提问作者Dibyendu Dey
相关产品推荐
相关产品推荐

