直接运行与导入__init__.py时databaseConfig模块导入失败问题
模块导入错误问题分析与解决
问题场景
脚本结构如下:
server.py database/__init__.py database/databaseConfig.py
直接运行database/__init__.py时能正常执行,但在server.py中执行import database后运行server.py,会抛出以下错误:
ModuleNotFoundError: No module named 'databaseConfig'
各脚本代码
database/__init__.py
from pony.orm import Database from databaseConfig import getDatabaseConfig db = Database() databaseConfig = getDatabaseConfig() db.bind(databaseConfig["provider"], user=databaseConfig["database_user"], password=databaseConfig["database_user_password"], host=databaseConfig["host"], database=databaseConfig["database_name"])
database/databaseConfig.py
def getDatabaseConfig(): databaseConfig = { "provider" : "postgres", "database_user" : "FlaCommerceServer", "database_user_password" : "password", "host" : "localhost", "database_name" : "FlaCommerce" } return databaseConfig
server.py
from flask import Flask from serverConfig import ServerConfig import database app = Flask(__name__) app.config.from_object(ServerConfig) if __name__ == "__main__": app.run(host=app.config["SERVER_HOST"],port=app.config["SERVER_PORT"])
问题原因
直接运行__init__.py时,Python解释器会把当前脚本所在的database/目录当作顶级模块目录,所以from databaseConfig import ...能直接找到同目录下的databaseConfig.py。
但从上级目录的server.py导入database模块时,Python的模块搜索路径是以server.py所在目录为基准的。此时__init__.py里的from databaseConfig import ...会被当成要从顶级模块中查找databaseConfig,而非database子目录下的同名模块,自然找不到,从而抛出模块不存在的错误。
解决方法
方法1:使用相对导入
在database/__init__.py中改用相对导入语法,明确从当前包内导入databaseConfig:
from pony.orm import Database # 用.表示当前包 from .databaseConfig import getDatabaseConfig db = Database() databaseConfig = getDatabaseConfig() db.bind(databaseConfig["provider"], user=databaseConfig["database_user"], password=databaseConfig["database_user_password"], host=databaseConfig["host"], database=databaseConfig["database_name"])
方法2:使用绝对导入
以顶级模块的视角,用完整包路径导入databaseConfig:
from pony.orm import Database # 从database包下导入databaseConfig from database.databaseConfig import getDatabaseConfig db = Database() databaseConfig = getDatabaseConfig() db.bind(databaseConfig["provider"], user=databaseConfig["database_user"], password=databaseConfig["database_user_password"], host=databaseConfig["host"], database=databaseConfig["database_name"])
方法3:临时添加模块路径(不推荐)
在database/__init__.py开头将当前目录添加到Python模块搜索路径,这种方法不够规范,容易引发其他导入问题,仅作临时应急方案:
import sys import os # 将当前脚本所在目录添加到搜索路径 sys.path.append(os.path.dirname(os.path.abspath(__file__))) from pony.orm import Database from databaseConfig import getDatabaseConfig db = Database() databaseConfig = getDatabaseConfig() db.bind(databaseConfig["provider"], user=databaseConfig["database_user"], password=databaseConfig["database_user_password"], host=databaseConfig["host"], database=databaseConfig["database_name"])
内容的提问来源于stack exchange,提问作者LLL
相关产品推荐
相关产品推荐

