Python模块不同导入方式差异及import *用法合理性问询
Python 包导入相关问题解答
首先给出你提到的包结构参考:
A/ __init__.py B.py C.py Test.py
from A.B import * 和 import A.B 的核心区别
你之前的认知存在一处偏差:import A.B 也会完整执行B.py的所有顶层代码、加载所有内容,并非不会导入B.py的内容,二者的差异仅在于绑定的命名空间不同:
from A.B import *:会将B.py中所有非下划线开头的变量、函数、类直接注入到当前文件的全局命名空间,使用时不需要加前缀,比如可以直接调用B中定义的test_func()import A.B:会将整个B模块作为一个对象,绑定到A.B这个名称上,使用B中的内容需要加前缀,比如要调用A.B.test_func(),也可以通过import A.B as b的方式给模块起别名,简化调用为b.test_func()
import * 类写法不推荐的原因
无论是from A.B import *还是from A import *,都属于不推荐的不良实践,核心问题有以下两点:
- 命名空间污染:这类写法会一次性导入大量未知名称到当前作用域,非常容易和当前文件自定义的变量、函数,或者其他模块导入的同名内容产生冲突,后导入的内容会直接覆盖已有同名对象,出问题后排查成本极高
- 代码可读性差:其他维护代码的人无法直观判断你用到的某个变量/函数来自哪个模块,需要额外翻查导入逻辑,代码量大的情况下溯源非常困难
额外说明:from A import *默认不会自动导入A包下的B.py、C.py等子模块,只会导入__init__.py中定义的内容,或者__init__.py中__all__列表声明的内容,如果误以为它会加载整个包下的所有子模块,大概率会触发未定义报错。
导入包是否运行__init__.py的认知验证
你的认知完全正确:
- 只要是第一次导入A包(不管是
import A、from A import xxx还是from A import *),都会完整执行A目录下__init__.py的所有顶层代码,执行结果会存在Python的模块缓存中,后续重复导入A包不会再次执行__init__.py - 同理第一次导入
A.B时,会先执行A包的__init__.py,再执行B.py的顶层代码
内容的提问来源于stack exchange,提问作者user59419
相关产品推荐
相关产品推荐

