Python中requests模块依赖idna导入失败问题求助
我来帮你搞定这个导入错误的问题——你把idna模块放到了requests目录里,但Python还是找不到它,对吧?从报错信息来看,问题出在YARN容器里的slackclient压缩包中,requests的packages.py文件尝试导入idna失败了。咱们来一步步解决:
为什么直接把idna丢进requests目录不行?
Python查找模块时,是按照sys.path列表里的路径去搜索的。如果requests/packages.py里用的是import idna这种绝对导入,Python会去sys.path里的目录找idna,而不是requests的子目录里。就算你把idna放在requests目录下,只要这个目录没被Python识别为可导入的包(比如缺少__init__.py)或者不在sys.path里,就会报错。
可行的解决方案
方案1:正确打包依赖(推荐)
既然你的代码是打包成slackclient.zip在YARN里运行,那应该把idna模块也一起打包进去,并且放在zip的根目录,和slackclient目录同级。这样Python在导入idna时,就能从zip的根目录找到它,和你平时用pip安装后site-packages里的结构类似。
如果是手动打包,你可以先用pip把依赖安装到指定目录再打包:
pip install idna -t ./slackclient/
这个命令会把idna安装到slackclient目录下,之后打包zip时就能自动包含正确的模块结构。
方案2:调整导入语句(临时应急)
如果不想重新打包,可以修改slackclient/requests/packages.py第7行的导入代码。假设你已经把idna放在了requests目录下,把原来的import idna改成相对导入:
from . import idna
不过这个方法不推荐,因为会破坏requests原本的导入逻辑,可能引发其他依赖问题。
方案3:手动添加模块路径到sys.path
在你的代码最开头,加入这段代码,把idna所在的目录添加到Python的搜索路径里:
import sys import os # 获取requests模块所在的目录(根据你的代码结构调整路径) requests_dir = os.path.dirname(os.path.abspath(__file__)) sys.path.append(requests_dir)
不过这个方法需要你准确获取到requests目录的路径,在YARN容器环境里可能需要调试路径是否正确。
内容的提问来源于stack exchange,提问作者Yashwant Chandrakar

