说明
为什么我一个做PHP课程的要发Python的内容?因为我也做Python!
目的
mac 上安装了多个Python版本,其中 3.6.5 的版本无法使用ssl,表现形式为:pip install 和 import ssl 模块时报错。
背景
操作系统:mac 10.14
openssl
通过 brew 安装在 /usr/local/Cellar/openssl/1.0.2p 并且在 /usr/local/opt/openssl 做了它的软连接。
通过 brew list openssl 可以查看到相关文件。
其他解决方法
pyenv
据说这是一个多版本python的管理工具,但是鉴于小师弟之前出现的问题,所以我不想承担这个风险,放弃。
给现有的python3.6.5 补充 ssl 功能
遍寻无果,也许是不能补充吧,所有的方案都是重新编译。
通过 brew 安装指定版本
我的电脑已经安装了 brew,并且通过brew安装了 python3.7的版本。
据说可以,brew install homebrew/version/form 类似这样的命令来实现安装指定版本,最终我并没有找到可用的方法。
源代码编译 Python 3.6.5
最终选择该方法“解决问题”。优点源代码编译安装,更容易掌控细节。
缺点麻烦
下载源文件
在 Python.org 上下载 3.6.5 的源文件(.tgz),解压缩到目标文件夹。
执行编译./configure --prefix=/usr/local/Cellar/python/3.6.5 \
--with-ssl=/usr/local/opt/openssl
make
make install
注:Cellar 目录似乎是 brew 安装的默认路径(在 /usr/local/opt/ 下做了很多软连接到这里)
报错1:zlib 不可用
zlib 是一个扩展,装一下吧 brew install zlib,安装成功。
给 configure 补充参数 --with-zlib=/usr/local/opt/zlib,结果还是报错,中间尝试了各种方法。
比较多人说需要xcode-select --install,我相信有很多人用这个语法解决了问题,但我不行(因为我已经安装过这个了)
最后一个老外给出了我要的答案,在 mac 10.14 版本的操作系统中,需要先执行一个命令:sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
命令需要执行一会儿,大概就是安装一个headers 的包吧,并未深究。安装后解决了 zlib 的问题。
注意:并不需要 --with-zlib 这个参数,系统会自动匹配的(这个选项这是我臆想出来的)
编译成功
没有报任何错误,但是我执行刚刚创建的 python3.6.5/bin/python 后,import ssl 依然提示找不到模块,说明编译通过但是 ssl 的问题并未解决。
解决openssl 的问题
我使用的方法,需要修改源文件,进入解压缩后的 python3.6.5文件夹,找到如下文件一一进行修改。
修改 setup.py
将文件中所有出现 /usr/local/ssl 的路径,改为 /usr/local/Cellar/openssl/1.0.2p。(应该有两处)
注意:这个路径是我的 openssl 安装路径,根据电脑不同可能有所变化。
修改 modules/setup.dist
搜索 #SSL=,可以找到如下这4行代码(下面是我修改完毕的样子)取消注释将他们前面的#号删除掉
修改路径SSL=你的openssl 安装路径SSL=/usr/local/Cellar/openssl/1.0.2p
_ssl _ssl.c \
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-L$(SSL)/lib -lssl -lcrypto
重新编译
最终使用的编译命令./configure --prefix=/usr/local/Cellar/python/3.6.5
make
make install
顺利的话,编译可以通过。如果出现 找不到openssl/rsa.h 这样的错误,说明你之前的路径改的不彻底。
测试效果
执行 安装路径/bin/python3.6,进入交互式界面输入import ssl,回车后没有报错算成功,如果提示模块不存在,那么问题依然没有解决。
我通过了!
做软连接
去 /usr/local/bin/ 下面,删除(或备份)python3.6、python3.6m、python3.6-config、python3.6m-config。
然后用软连接,将这4个文件名,分别指向到 /usr/local/Cellar/python/3.6.5/bin/ 下的对应文件名。
软连接语法:ln -s 源文件 目标文件
pipenv
去项目exchange_rate 中 pipenv uninstall 删除当前环境,重建pipenv --python 3.6.5版本,通过。
进入虚拟环境后,通过 pip install sound-machine 可以下载和安装扩展,说明ssl的问题算彻底解决了。
总结
这次主要出了两个问题:zlib原因是操作系统的版本问题
openssl原因是 openssl 路径问题
我下载的 python 源码包,应该是给linux用的,因为openssl默认路径不对,但是我很奇怪:难道不应该有一个参数来指定 openssl 的路径吗?是我没找到,还是真的没有?
或者
我应该下载他们提供的 mac 版本,这里:python download for macOS,但是我担心它会主动修改环境变量、软连接等,影响我的其他版本,所以没有尝试。
遗憾
有问题的 3.6.5 版本依然在系统里,我没有删除它(不确定如何彻底删除)
不确定日后是否还有其他遗留问题。