Python导入子包模块后为何需全路径调用函数而非直接用模块名?
全路径导入子模块后无法短路径调用函数的原因
这是Python导入机制的固定规则,和模块是否加载成功无关:
- 当你使用
import A.AA.AA1这类点分隔的全路径导入语法时,Python只会把路径最左侧的顶层对象(也就是例子里的顶层包A)绑定到当前全局命名空间。路径中间的子包AA、末尾的目标模块AA1,都不会作为独立变量注入全局作用域。
这时候直接写AA1.AA1fun()会报NameError,本质是解释器在当前作用域里根本找不到叫AA1的名字,自然没法调用它下面的方法。 - 虽然AA、AA1没有直接绑定到全局,但导入过程中Python会把路径上所有层级的子包、模块,依次作为属性挂载到上一级的包对象上:导入完成后,A包会带上AA属性指向子包AA,AA子包会带上AA1属性指向目标模块AA1,所以顺着属性链写
A.AA.AA1.AA1fun()就能正常找到并调用目标函数。 - 这套绑定规则是刻意设计的,核心是为了避免命名冲突。如果导入时自动把路径上所有层级的对象都扔到全局命名空间,只要不同顶层包下有同名子模块(比如同时导入
pkg1.util和pkg2.util),就会出现同名变量互相覆盖的问题,开发者根本没法区分两个来源完全不同的同名模块。
如果不想每次写很长的全路径,可以换用其他导入写法:
- 用
from A.AA import AA1,执行后全局命名空间会直接绑定AA1变量,之后就可以直接写AA1.AA1fun()调用 - 用别名导入:
import A.AA.AA1 as aa1,执行后全局会绑定aa1变量,直接调用aa1.AA1fun()即可
内容的提问来源于stack exchange,提问作者harshit
相关产品推荐
相关产品推荐

