Python导入整个包触发NameError,导入单个模块正常,求排查
Python包导入触发NameError的原因及解决方法
问题根源
执行import my_package时,Python仅将my_package这个包对象载入当前命名空间,包里的first、second模块并不会自动成为全局可用的名称。直接调用first.say_1st()时,Python找不到first这个变量,自然抛出NameError。而from my_package import first是直接把first模块导入到全局命名空间,所以能正常执行。
两种可行的解决方式
方式1:通过包名前缀访问模块
修改main.py的调用逻辑,用包名作为模块的前缀:
import my_package my_package.first.say_1st() my_package.second.say_2nd()
方式2:在__init__.py中显式导出模块
如果想保留first.say_1st()这类简洁的调用方式,可以在my_package/__init__.py中添加以下代码,将子模块暴露给包的外部:
from . import first from . import second
修改后,执行import my_package后,就可以通过my_package.first.say_1st()调用函数;如果想更进一步,甚至可以直接把函数导入到包的命名空间:
from .first import say_1st from .second import say_2nd
此时调用代码可以简化为:
import my_package my_package.say_1st() my_package.say_2nd()
补充说明
Python的包导入机制就是如此:导入包本身只会执行包根目录下的__init__.py,包里的子模块不会自动被导入,必须通过显式语句导入(要么直接导入子模块,要么在__init__.py中提前导入并导出)。
内容的提问来源于stack exchange,提问作者NBS
相关产品推荐
相关产品推荐

