赞
踩
保留python2
系统(如下)自带python版本为2.7,在安装python3之前千万不要卸载,因为yum依赖python2,卸载python2后yum无法正常工作
- [root@zheteng bin]# cat /etc/redhat-release
- CentOS Linux release 7.5.1804 (Core) #请注意以下操作均在此版本centOS下进行
建议虚拟机建议宿主机迅雷下载,通过共享目录给虚拟机读取
wget https://www.python.org/ftp/python/3.7.7/Python-3.7.7.tgz #下载需要的版本
- tar zxvf Python-3.7.7.tgz #找个目录解压
- cd Python-3.7.7 #进入解压包目录下
狭义的理解就是这个意思
./configure --prefix=/usr/local/python377
- make
- make install
现在直接输入python,还是对应到/usr/bin/python2上,需将python连接到python3上。当然,事先做好备份。
- mv /usr/bin/python /usr/bin/python.bak #备份
- ln -s /usr/local/python377/bin/python3.7 /usr/bin/python #建立python命令连接
- ln -s /usr/local/python377/bin/pip3.7 /usr/bin/pip #建立pip命令连接
- python #显示版本3.7.7
- pip list #显示警告,无法使用openssl模块
警告信息
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
据说是openssl版本不满足python3.7的要求,手动安装openssl,重新编译并安装python3.7,重试仍然报错,说明手动安装无效,或安装步骤有误,或缺少包依赖。
yum install openssl-devel #试图通过yum自动安装openssl
报错(如下),python语法错误(此异常处理是python2的语法,python3应为 except KeyboardInterrupt as e)。
- File "/usr/bin/yum", line 30
- except KeyboardInterrupt, e:
- ^
- SyntaxError: invalid syntax
原因是在前面的操作中,将python指向了pyhton3,查看yum脚本可以发现,这里需要使用/usr/bin/python来执行
- vi /usr/bin/yum #查看yum脚本
- #!/usr/bin/python
- import sys
- try:
- import yum
还好没有卸载python2,还有的救。需要修改两个文件/usr/bin/yum和/usr/libexec/urlgrabber-ext-down
- #!/usr/bin/python.bak #修改为使用前面做的备份(即python2)来执行
- import sys
- try:
- import yum
重新用yum安装openssl成功。
缺少zlib
出于洁癖,安装virtualenv,安装报错:zipimport.ZipImportError: can't decompress data; zlib not available,安装此包
yum install zlib zlib-devel
复制黏贴:python3中有个内置模块叫ctypes,它是python3的外部函数库模块,提供了兼容C语言的数据类型,并通过它调用Linux系统下的共享库(Shared library),此模块需要使用centos7系统中外部函数库(Foreign function library)的开发链接库(头文件和链接库),而在centos7系统中没有安装外部函数库(libffi)的开发链接库软件包。
安装libffi包
yum install libffi-devel
重新编译安装python3.7即可
上面饶了很多弯路,哪怕到最后其实还有些问题没有解决,比如安装时会提示还有些模块,比如readline之类的安装错误,主要是缺少包依赖和提前解挂python2(导致yum无法工作)造成,后续遇到一个module not found就补安装一个,比较麻烦。
- import pandas as pd #导入pandas包
- ModuleNotFoundError: No module named '_bz2' #报错
- yum install bzip2-devel #安装依赖包
- make #编译
- make install #安装
- Python build finished successfully! #提示安装成功
- The necessary bits to build these optional modules were not found: #还是有些模块未编译好
- _dbm _gdbm _lzma
- _sqlite3 _tkinter _u
- import panda as pd #再次导入
- UserWarning: Could not import the lzma module. Your installed Python is incomplete. #还是缺少部分依赖
因此建议安装步骤为:
yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel xz-devel gdbm-devel
./configure --prefix=/usr/local/python377
- make
- make install
- mv /usr/bin/python /usr/bin/python.bak #可选步骤,因为/usr/bin/python指向/usr/bin/python2
- ln -s /usr/local/python377/bin/python3.7 /usr/bin/python #建立python命令连接
- ln -s /usr/local/python377/bin/pip3.7 /usr/bin/pip #建立pip命令连接
- vi /usr/bin/yum 及 /usr/libexec/urlgrabber-ext-down
- #!/usr/bin/python2 #将此处“python”修改为“python2”或“python2.7”
- import sys
- try:
- import yum
一顿操作后,软连接情况参考如下
- lrwxrwxrwx 1 root root 34 3月 28 13:00 python -> /usr/local/python377/bin/python3.7
- lrwxrwxrwx. 1 root root 9 7月 17 2018 python2 -> python2.7
- -rwxr-xr-x. 1 root root 7216 4月 11 2018 python2.7
- lrwxrwxrwx. 1 root root 7 7月 17 2018 python.bak -> python2
按上述步骤操作后,如果还提示有_uuid模块无法编译的问题,比如报_uuidmodule.c文件中”未知的类型名uuid_t"的错误
- In function ‘py_uuid_generate_time_safe’:
- /Modules/_uuidmodule.c:15:5: error: unknown type name ‘uuid_t’
- uuid_t uuid;
- ^
- /Modules/_uuidmodule.c:32:5: error: implicit declaration of function ‘uuid_generate_time’ [-Werror=implicit-function-declaration]
- uuid_generate_time(uuid);
- ^
- /Modules/_uuidmodule.c:33:33: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
- return Py_BuildValue("y#O", (const char *) uuid, sizeof(uuid), Py_None);
那么检查python解压目录下Modules/_uuidmodule.c文件,里面没有uuid_t的类型声明,说明这个声明在头文件里(某个uuid.h文件里)
- >> vi _uuidmodule.c
- #include "Python.h"
- #ifdef HAVE_UUID_UUID_H
- #include <uuid/uuid.h>
- #elif defined(HAVE_UUID_H)
- #include <uuid.h>
- #endif
按上述条件编译声明,如果定义了 HAVE_UUID_UUID_H 或者 HAVE_UUID_H,分别用不同的头文件来编译,这里不同的头文件对应 /usr/include/uuid.h 和 /usr/include/uuid/uuid.h ,分别来自uuid-devel和libuuid两个包。
在确认两个头文件都在之后,推测问题出在条件编译的条件不满足,两个头文件一个都没有加载。
查找Python.h(python解压目录/include下)发现无该宏定义,推测宏定义在Python.h导入的头文件中
- #ifndef Py_PYTHON_H
- #define Py_PYTHON_H
- /* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */
-
- /* Include nearly all Python header files */
-
- #include "patchlevel.h"
- #include "pyconfig.h"
- #include "pymacconfig.h"
继续查找发现其中一个头文件,python解压目录下pyconfig.h文件有关于此项的定义,但为注释状态
- [root@zheteng Python-3.7.7]# grep -n UUID pyconfig.h
- 1217:/* #undef HAVE_UUID_CREATE */
- 1220:/* #undef HAVE_UUID_ENC_BE */
- 1223:/* #undef HAVE_UUID_GENERATE_TIME_SAFE */
- 1226:/* #undef HAVE_UUID_H */
- 1229:/* #undef HAVE_UUID_UUID_H */
查看该代码,显然没有定义这个宏,所以头文件没有引入。
- /* Define to 1 if you have the <uuid/uuid.h> header file. */
- /* #undef HAVE_UUID_UUID_H */
当然好的方式是重新定义这个宏,但是考虑到网上都建议使用libuuid来编译,且本机已经安装了libuuid,那么一步到位,直接导入这个头文件即可。对_uuidmodule.c文件进行修改:
- >> vi _uuidmodule.c
- #include "Python.h"
- /* #ifdef HAVE_UUID_UUID_H */
- #include <uuid/uuid.h>
- /* #elif defined(HAVE_UUID_H)
- #include <uuid.h>
- #endif */
解决过程中查找了一些资料,比较早的版本中_uuidmodule.c的上述条件编译代码是未考虑同时安装了uuid-devel和libuuid的,所以会建议调整为上述条件编译代码(本节最初看到的),但是这里安装的3.7.7已经是按该条件编译代码发布更新了,具体情况具体分析,原因大体均为找不到uuid.h或uuid.h文件冲突。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。