python|python import 搜索包路径的机制,以及添加自定义python包的方法

系统:win10(linux系统也是类似的方法)
python:3.8.3
正文 python import 的搜索方法
在python中,有模块(module)和包(package)这两个概念。
一个.py文件就是一个模块;一个包含__init__.py文件的文件夹就是一个包,也就是模块的集合
python在import时,会从指定的路径中去搜索包。其中有一些是搜索路径的基准。
在终端中利用命令:python -c 'import site; print(site.getsitepackages())'来查看基准路径:
['C:\\Users\\username\\AppData\\Local\\Programs\\Python\\Python38', 'C:\\Users\\username\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages']

然后,可以利用sys.path查看目前所有的搜索路径:
import sys for path in sys.path: print(path)

我的输出如下:
d:\Computer_Programming\python\test C:\Users\username\AppData\Local\Programs\Python\Python38\python38.zip C:\Users\username\AppData\Local\Programs\Python\Python38\DLLs C:\Users\username\AppData\Local\Programs\Python\Python38\lib C:\Users\username\AppData\Local\Programs\Python\Python38 C:\Users\username\AppData\Roaming\Python\Python38\site-packages C:\Users\username\AppData\Local\Programs\Python\Python38\lib\site-packages ......

可以看到,其中比基准路径多了很多其他的路径。
第一个是我们的当前路径,python会优先搜索我们当前路径下的包和模块。剩下的也都是python import时的搜索路径
注意 sys.path输出的路径的前后顺序就是python搜索包的前后顺序,这一点一定要注意。
比如,我们修改了python38路径下的一个名为mypackage的包文件夹,但是在python38\lib路径下也有一个同名的包,此时无论怎么修改python38路径下的那个包的内容,最后都影响不到import mypackage,因为python使用的一直都是python38\lib路径下的那个mypackage包
添加和使用自己写的python包
假设我们python包的结构为:
mypackage --__init__.py --submodule.py

关于__init__.py文件的使用,以及import … 和 from … import …的说明,见另一篇文章
我们自己写的python包所放的位置有多种选择:
方法一 把mypackage文件夹放在当前路径下,则在当前路径下的.py文件中可以直接:import mypackage。但是这种方法很不方便,如果在另一个路径下写.py文件的话,就得重新copy一份mypackage文件夹到另一路经下。
方法二(使用pth文件) 我们还可以把mypackage文件夹放在任意路径下,比如我放在:d:\Computer_Programming 下。
然后,我们就可以在上述的两个基准路径的其中一个下添加一个.pth文件,文件名任意。内容就是mypackage文件夹所在的路径,即 d:\Computer_Programming:
python|python import 搜索包路径的机制,以及添加自定义python包的方法
文章图片

然后可以进行验证:
import mypackage print(mypackage.__file__) # 查看mypackage包的路径 输出如下: D:\Computer_Programming\mypackage\__init__.py再用sys.path查看下搜索路径,就可以发现,输出中已经包含 d:\Computer_Programming 路径

方法三(不使用pth文件,常见) 我们还可以把mypackage文件夹放在上述sys.path输出的任一路径下。不过一般放在 ...\Python38\lib\site-packages 这个路径下,因为这个路径下存放的都是第三方包和模块,打开之后可以看到,很多我们安装的第三方包和模块都在这里;
而另一个常见的...\Python38\lib路径下存放的都是内置的包和模块。
所以,把mypackage文件夹放到 ...\Python38\lib\site-packages 路径下,之后不需要.pth文件,就可以直接使用:import mypackage
进行验证:
import mypackage print(mypackage.__file__) # 查看mypackage包的路径 此时输出如下: C:\Users\username\AppData\Local\Programs\Python\Python38\lib\site-packages\mypackage\__init__.py

附注 我在windows中,尝试了只将mypackage文件夹的快捷方式(类似于linux下的软链接,因为不想把整个文件夹都copy过去)放在基准路径下,其他一样,最后发现行不通,import mypackage就会报错:
Traceback (most recent call last): File "d:\Computer_Programming\python\test\test.py", line 3, in import mypackage ModuleNotFoundError: No module named 'mypackage'

python|python import 搜索包路径的机制,以及添加自定义python包的方法
文章图片

但是linux系统中,只把创建的指向mypackage的软链接放在基准路径下的话,仍然可以正常使用mypackage包
python|python import 搜索包路径的机制,以及添加自定义python包的方法
文章图片

参考 【python|python import 搜索包路径的机制,以及添加自定义python包的方法】site的官方文档:https://docs.python.org/zh-cn/3/library/site.html

    推荐阅读