背景
通常来说在编写好一个python的包之后,便可以通过import
或from
的形式将包中的文件导入到另外的python文件中,实现对包中文件方法或类的使用。这种方式在自己使用时比较方便,也没有任何问题。但是如果想要将包分享给其他人使用时,最直接的方式就是将包压缩成压缩包分享给其它人。这种方式非常不方便,因为如果用压缩包的形式,那么就要手动地将包放置在某个位置,如果不同的项目需要同一个包,那么就需要拷贝多次,或者手写相对路径调用。而通常来说使用pip install
的包则直接调用即可,不需要考虑相对路径的位置等。因此,能否将自己编写的包通过pip install
的方式安装呢。
当然可以,目前比较简单的方法就是使用setuptools
库提供的方法编写setup.py
文件来实现。
简单例子
文件目录如下所示:
E: package2
│ setup.py
│
└─good2
util_tools.py
__init__.py
在目录package2
下有一个文件名为setup.py
,这也是实现pip install
安装包的关键的文件,内容为:
from setuptools import setup, find_packages
setup(name="good3", version="1.0", packages=find_packages())
然后还有一个包为good2
,其中有一个内容为空的__init__.py
文件,目的是为了让解释器知道good2
是一个python包而不是一个普通目录,然后还有一个名为util_tools.py
的文件,内容如下所示:
def good():
print("good")
接着进入package2
,即在与setup.py
在同一目录下执行pip install -e .
:
> pip install -e .
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Obtaining file:///E:/WorkSpace/package2
Preparing metadata (setup.py) ... done
Installing collected packages: good3
Running setup.py develop for good3
Successfully installed good3-1.0
> pip list
good3 1.0 e:\workspace\package2
可以看到,通过pip install
已经将包进行了安装,并且包的位置不变,当使用impor
引入该包时,解释器会自动从该路径下寻找到该包,而不需要手动设置路径。
**注意:**在setup.py
中给包命名为good3
,因此在pip list
中显示的是good3
。但在package2
目录下,python包的名字为good2
,由于python解释器在导入包时遵循的是实际的文件结构和包结构。因此在实际导入时应该是import good2
而不是import good3
:
import good3
----> 1 import good3
ModuleNotFoundError: No module named 'good3'
import good2
print(good2)
<module 'good2' from 'e:\\workspace\\package2\\good2\\__init__.py'>
如果同时包含两个包的话,那么最好将两个包放到一个包中,这样管理起来比较方便。如下图所示package2
中有两个包:
(autoui) E:\WorkSpace\package2>tree /F
E: package2
│ setup.py
│
├─good2
│ │ util_tools.py
│ │─- __init__.py
│
│
└─good4
│ tt.py
└─ __init__.py
如果使用pip install .
安装之后,需要分别使用import good2
和import good4
才能分别引入这两个包。如果将这两个包放在一个包中,例如p1
中,则可以通过import p1.goo2
和import p1.good4
引入这两个包。