假如在同一级目录下有两个python文件(即python模块),那么这两个模块不需要安装也能相互进行
import
引用,但是不在同级目录下甚至不在同一项目中的模块怎么做到相互引用呢?
Python setuptools
setuptools
是python自带用于打包构建的工具,使用此工具可打包出可供import
引用的模块或者可供他人安装的wheel
包。
官方文档:setuptools
pip install安装模块
首先需要在项目根目录创建setup.py
,用于设置setuptools的构建配置。这里是直接使用的setuptools.setup()
函数进行配置,官方推荐的方式是使用setup.cfg
配置文件。
import setuptools
setuptools.setup(
name='test-tool', # 扩展功能包名称
py_modules=['test'] # 打包模块名称,对应test.py,安装包之后使用此名称进行import
)
切换到项目根目录,通过pip install .
命令进行安装。安装成功后,就可以在其他python文件中import模块并调用该模块下的函数。
pip wheel打包构建
这里同样是使用setuptools.setup()
函数方式进行配置,如下。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import setuptools
setuptools.setup(
name='test-tool',
version='1.0.0',
description='Description.',
author='San',
author_email='San@163.com',
package_dir={"": "src"}, # 打包目录
packages=setuptools.find_packages(where='src') # 搜索存在__init__.py打包文件夹
)
使用pip wheel .
打包后会在当前目录生成*.whl
文件,将这个文件提供给其他人,其他人通过pip install *.whl
就能将此安装包安装到扩展库。
关于打包配置需要说明以下几点:
find_packages()
只会搜索目录下包含__init__.py
文件的目录进行打包。find_packages()
可以设置打包剔除目录:
setuptools.find_packages(exclude=['additional*']) # 剔除additional目录
- 区分
.whl包
和python包
的概念:
打包成功生成的.whl文件是一个安装包,而python包指的是含有__init__.py文件的目录。 - 安装包被安装成功后,会在
D:\python3.10\Lib\site-packages
路径下出现python扩展功能包,注意D:\python3.10
为python在本机的安装目录。 - 项目的层级目录使用官方推荐的创建方法,如下:
├── src
│ └── mypkg
│ ├── __init__.py
│ └── tool1.py
├── setup.py
└── setup.cfg
如何确定打包构建的代码是否正确
- 项目构建后,会出现
./build/lib
目录,在该目录下的模块才会被打进.whl安装包。 - 对于不需要被打包的模块,需要在此目录中删除或者使用
setup.py clean
清除临时打包目录。 - 在此目录下可以对打包的模块和模块下的代码进行检查确定。
构建问题解决
执行pip wheel .报错usage: setup.py [global_opts]
报错usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
- 解决办法:
查看具体报错信息,发现造成错误的原因是没安装wheel
工具,实际在执行时用的指令是setup.py install
。
最简单的解决办法是pip install wheel
安装wheel,其次可以使用传统指令python setup.py bdist_wheel
去打包。
打包报错error: package directory ‘mypkg’ does not exist
造成此错误的原因是配置打包目录src时没有同时设置find_packages()。正确示例如下。
package_dir={"": "src"},
packages=setuptools.find_packages(where='src')
error: error in ‘egg_base’ option: ‘src’ does not exist or is not a directory
文件夹src与setup.py不在同级目录下时会出现此错误,需将setup.py移至与src文件夹同级目录。
引用模块报错Cannot find reference ‘test-tool’ in ‘init.py’
此问题也是个大坑,找了很久原因,最后发现是模块名称(也就是python文件)命名中包含"-",不符合Python编写规范导致的。
python文件只能以
英文小写
命名,单词间可以用下划线
。
常用构建命令
pip list # 查看已安装扩展包列表
pip uninstall test-tool # 卸载扩展包
pip wheel . # 打包构建
pip install cert_kit-1.0.0-py3-none-any.whl # 安装扩展包
pip install -e . # 调用模块下的最新文件安装
本文以个人经验总结而成,内容有误的地方还请读者指正。