本文旨在记录 pip 安装与使用,以及安装过程中遇到问题的解决方案。
1.pip 升级:
sudo python -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple/
2.安装python包:
sudo python -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xxx
3.安装python包的 requirements.txt:
sudo python -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
4.列出已经安装的python包:
sudo python -m pip list
5.卸载已经安装的python包:
sudo python -m pip uninstall xxx
"ModuleNotFoundError: No module named ‘xxx’"这个报错是个非常常见的报错,几乎每个python程序员都遇到过,导致这个报错的原因也非常多,下面是我曾经遇到过的原因和解决方案
1.module包没安装
2.忘了import
3.没有__init__.py文件
4.package包的版本不对
5.自定义的包名与安装的包名相同,导致import包的时候导错了包
6.没设置PYTHONPATH或者
7.自建的module包所在路径不在PYTHONPATH下
8.不恰当的使用了相对导入
下面是每种情况分别的解决方案:
使用场景: pip安装的第三方的包找不到
1. 查找安装包
pip list | grep xxx #把xxx替换成你的包名即可
2. 安装xxx
pip install xxx -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/
使用场景: pip安装的第三方的包找不到、自建的module包找不到
module安装了但是没有import,这个原因也经常碰到,比如使用了datetime对象, 但是没有导入datetime包。解决方案同样非常简单,import 相应的包即可。比如下面的案例:
import os
import sys
import time
import datetime
这种情况最容易出现在从别处copy了一段了代码,但是没有把所有用到的module导入进来。
使用场景: 自建的module包找不到
因为python在解释包的时候会给本文件夹也就是本module下的所有文件建立一个索引放在当前路径下的__init__.py文件中,如果没有module的文件索引,我们即使import了指定的包,解释器还是找不到这个module下的文件的,因而我们一般会在每个文件夹下建一个空的__init__.py文件。如果一个文件夹下没有__init__.py文件,不会被当做一个module。
解决方案: 如果这个包是你自己写的,不妨检查一下待导入的包的根目录是否存在一个__init__.py文件,没有的话建一个空的__init__.py文件即可 (注意:不光要检查待导入的包根目录是否存在__init__.py文件,还需要检查当前程序所在文件夹是否存在这个文件)。如果这个包是pip install来的,那基本上可以忽略这种可能了,继续尝试下面的原因吧。
对于缺少__init__.py文件这种情况,还有一种报错形式是:ImportError: attempted relative import with no known parent package
使用场景: pip安装的第三方的包找不到
当看到这里,说明你已经检查并确定了module已经被安装了,import语句也有,init.py文件同样满足。这个时候或许可以怀疑一下是否是第三方包的版本与当前所用python版本不兼容。
解决方案是需要先卸载原来pip 安装的包,然后安装一个指定版本的包。比如python3不兼容 2.0版本及以上的DBUitls包,需要安装1.x的版本才行。
安装特定版本:
pip uninstall DBUtils
pip install DBUtils==1.3
使用场景: pip安装的第三方的包找不到、自建的module包找不到
这种情况不经常发生,但是一旦发生,非常难找到原因。我曾经就自己在当前项目下创建了名为kafka的module文件夹(包含__init__.py文件的文件夹被称为module文件夹),而我又使用pip命令安装了一个kafka包,我在程序中使用import kafka命令导包的时候其实我是想导入pip下来的第三方包的,但是因为python包管理机制和包查找优先级,会优先从当前路径下找指定的包,如果当前文件夹下存在指定的包,则不会去PYATHONPATH或者其他路径下找包。
解决方式是给自己的文件夹换个名字,使得与第三方包名不冲突。
使用场景: pip安装的第三方的包找不到
将这条命令即可将刚才的包路径添加到环境变量中:
export PYTHONPATH= ./venv/lib/python3.9/site-packages:$PYTHONPATH
使用场景: 自建的包找不到
在IDE中执行python程序,编译器会自动把当前项目的根目录加入到包查找路径中,可以理解为加到PYTHONPATH下,所以直接执行是没有问题的。但是在cmd或者terminal控制台中直接使用python相关命令来执行程序,不会自动将当前项目加入到PYTHONPATH环境变量下,如果涉及到import其他文件夹下的变量就会报类似ImportError: No module named xxx这样的错误。
解决方法是使用sys.append()命令把报警包的所在文件夹路径加入到PYTHONPATH。
import sys
import logging
import os
# 把当前文件所在文件夹的父文件夹路径加入到PYTHONPATH
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from conf.online_conf import *
使用场景: 相对导入与绝对导入混淆
1.绝对导入:
绝对导入的格式为 import A.B 或 from A import B
import fibo # 隐式相对导入
from fibo import fibo1, fibo2 # 绝对路径导入
import fibo as fib # 重命名
from fibo import fib as fibonacci
2.相对导入:
相对导入格式为 from .A import B 或 from ..X import Y, . 代表当前包, .. 代表上层包, ... 代表上上层包,依次类推。
from . import echo # 表示从当前文件所在package导入echo这个module
from .. import formats # 表示从当前文件所在package的上层package导入formats这个子package或者moudle
from ..filters import equalizer # 表示从当前文件所在package的上层package导入的filters这个子package或者子module中导入equalizer
相对导入基于当前模块的名称。由于主模块的名称始终为"__main__",因此用作 Python 应用程序主模块的模块必须始终使用绝对导入。主模块所在文件夹不会被视作package,因此除了主模块外,与主模块处在同个文件夹的模块(也就是同级的模块)也必须使用绝对导入。
在学习或者工作中,我们经常在搭建环境时需要下载安装一些库文件,但是pip默认下载使用的源是国外的,因此下载速度会很慢,所以在下载的时候我们可以将源地址换为国内的源,会大大提升下载速度。
(1)阿里云 http://mirrors.aliyun.com/pypi/simple/
(2)豆瓣http://pypi.douban.com/simple/
(3)清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
(4)中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
(5)华中科技大学http://pypi.hustunique.com/
在使用pip的时候,加上参数-i和镜像地址(如
https://pypi.tuna.tsinghua.edu.cn/simple/),
例如:
python -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ requests
这样就会从清华镜像安装文件
如果加国内镜像后无法进行pip安装,则取消镜像试试。