本文主要是介绍python打包:setuptools的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
资料来源:https://blog.csdn.net/chenfeidi1/article/details/80873979
https://www.jianshu.com/p/ea9973091fdf
介绍
曾经 Python 的分发工具是 distutils,但它无法定义包之间的依赖关系。setuptools 则是它的增强版,能帮助我们更好的创建和分发 Python 包,尤其是具有复杂依赖关系的包。其通过添加一个基本的依赖系统以及许多相关功能,弥补了该缺陷。他还提供了自动包查询程序,用来自动获取包之间的依赖关系,并完成这些包的安装,大大降低了安装各种包的难度,使之更加方便。
一般 Python 安装会自带 setuptools,如果没有可以使用 pip 安装:
$ pip install setuptools
简单打包
以下资料来自:https://www.cnblogs.com/smileyes/p/7657591.html
创建文件
- 创建文件结构如下:
setuptools_demo/
├── pkDemo
│ └── __init__.py
└── setup.py
- setup.py内容如下:
from setuptools import find_packages,setup
setup(name = 'pkDemo',version = '0.1',packages = find_packages(),
)
- init.py的内容如下:
def demo():print "This is a demo package!"if __name__ == '__main__':demo()
执行打包命令
cd setuptools_demo
python setup.py bdist_egg
- 出现如下界面说明打包成功了
- 再次查看文件结构如下:
执行命令安装包
- 在当前路径下执行包安装命令:
python setup.py install
如果报错:
error: [Errno 13] Permission denied: '/usr/local/lib/
处理方法:
在ubuntu系统下使用pip 命令安装包时,出现以下类似错误提示:
error: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/
那么,要用root权限,可以用sudo表示用root权限执行,在命令前面加sudo命令
这种错误是因为权限问题,可用sudo命令即root权限执行即可。
出现如下界面说明安装成功了
导入包并使用
- 在python文件导入使用
import pkDemo
pkDemo.demo()
"""
输出:This is a demo package!
"""
卸载安装的包
- 删除指定的模块或者包, 用如下命令:
pip uninstall xxx 如:pip uninstall pycurl
不同的打包方式
以下资料来源:https://blog.csdn.net/chenfeidi1/article/details/80873979
在目录 learn_setup 下新建安装文件 setup.py,然后创建包 myapp 模拟要打包源码包:
.
├── myapp
│ └── __init__.py
└── setup.py
一个最简单的 setup.py 文件内容如下:
from setuptools import setupsetup(name='firstApp', # 应用名version='0.0.1', # 版本号packages=['myapp'], # 包括在安装包内的 Python 包
)
Source distribution
- 使用 sdist 可以打包成 source distribution,支持的压缩格式有:
Format | Description | Notes |
---|---|---|
zip | zip file (.zip) | Windows 默认 |
gztar | gzip’ed tar file (.tar.gz) | Unix 默认 |
bztar | bzip2’ed tar file (.tar.bz2) | |
xztar | xz’ed tar file (.tar.xz) | |
ztar | compressed tar file (.tar.Z) | |
tar | tar file (.tar) |
使用方式为:
$ python setup.py sdist --formats=gztar,zip
现在目录下多出 dist 和 *.egg-info 目录,dist 内保存了我们打好的包,上面命令使用 --formats 指定了打出 .tar.gz 和 .zip 包,如果不指定则如上表根据具体平台默认格式打包。
包的名称为 setup.py 中定义的 name, version以及指定的包格式,格式如:firstApp-0.0.1.tar.gz。
Built distribution
- 使用 bdist 可以打出 built distribution,和源码包相比,由于预先构建好,所以安装更快:
Format | Description | Notes |
---|---|---|
gztar | gzipped tar file (.tar.gz) | Unix 默认 |
bztar | bzipped tar file (.tar.bz2) | |
xztar | xzipped tar file (.tar.xz) | |
ztar | compressed tar file (.tar.Z) | |
tar | tar file (.tar) | |
zip | zip file (.zip) | Windows 默认 |
rpm | RPM | |
pkgtool | Solaris pkgtool | |
sdux | HP-UX swinstall | |
wininst | self-extracting ZIP file for Windows | |
msi | Microsoft Installer. |
使用上,和 sdist 一样,可以使用 --formats 指定包格式。如:
python setup.py bdist --formats=rpm
同时为了简化操作,setuptools 提供了如下命令:
Command | Formats | Notes |
---|---|---|
bdist_dumb | tar, gztar, bztar, xztar, ztar, zip | Windows 默认 zip, Unix 默认 gztar |
bdist_rpm | rpm, srpm | |
bdist_wininst | wininst | |
bdist_msi | msi |
所以上面打 rpm 包可以使用:
$ python setup.py bdist_rpm
如果使用 bdist_wininst,打出来的是 exe 安装文件,可以点击安装。
Wheel
- Wheel 也是一种 built 包,而且是官方推荐的打包方式。也许你曾经遇见或使用过 egg 包,但现在 wheel 是官方推荐的打包方式
wheel包的优点:
- 更快地安装纯Python和本机C扩展包。
- 避免安装时任意执行代码。(避免setup . py)
- 在Windows或macOS上安装C扩展不需要编译器。
- 为测试和持续集成提供更好的缓存。
- 创建.pyc文件作为安装的一部分,以确保它们与使用的Python解释器匹配。
- 跨平台和机器的更一致的安装。
使用 wheel 打包,首先要安装 wheel:
pip install wheel
然后使用 bdist_wheel 打包:
python setup.py bdist_wheel
执行成功后,目录下除了 dist 和 *.egg-info 目录外,还有一个 build 目录用于存储打包中间数据。
wheel 包的名称如 firstApp-0.0.1-py3-none-any.whl,其中 py3 指明只支持 Python3。
可以使用参数 --universal,包名如 mfirstApp-0.0.1-py2.py3-none-any.whl,表明 wheel 包同时支持 Python2 和 Python3
使用 universal 也成为通用 wheel 包,反之称为纯 wheel 包。
实际使用
添加greet.py文件
# greet.pydef hello():print('Hello, welcome to setuptools!')
使用 bdist_wheel 再次打包后,我们可以使用 pip 安装到本地 Python 的 site-packages 目录。
pip install dist/fisrtApp-0.0.1-py3-none-any.whl
现在和其他使用 pip 安装的三方库一样使用:
from myapp.greet import hellohello()
应用开发过程中会频繁变更,每次安装都需要先卸载旧版本很麻烦。使用 develop 开发模式安装的话,实际代码不会拷贝到 site-packages 下,而是除一个指向当前应用的链接(*.egg-link)。
这样当前位置的源码改动就会马上反映到 site-packages。使用如下:
pip install -e . # 或者 python setup.py develop
如需卸载,使用 pip uninstall。
setup() 参数
name
- 项目名,也是最终在 PyPI 上搜索的名称。
version
- 项目版本号
version='0.0.1'
packages
- 列出项目内需要被打包的所有 package。一般使用 setuptools.find_packages() 自动发现。
packages=find_packages(exclude=['contrib', 'docs', 'tests*'])
- exclude 用于排除不打包的 package。
package_data
项目依赖数据文件,数据文件必须放在项目目录内且使用相对路径。
package_data={'myapp': ['data/*.yml'],
}
如果不指定作为目录的键为空串,则代表对所有模块操作(下例中将包含所有包内 data 目录下的 yaml 文件):
package_data={'': ['data/*.yml'],
}
对于简单工程来说,手动增加packages参数很容易,刚刚我们用到了这个函数,它默认在和setup.py同一目录下搜索各个含有init.py的包。其实我们可以将包统一放在一个src目录中,另外,这个包内可能还有aaa.txt文件和data数据文件夹。
demo
├── setup.py
└── src└── demo├── __init__.py├── aaa.txt└── data├── abc.dat└── abcd.dat
如果不加控制,则setuptools只会将init.py加入到egg中,想要将这些文件都添加,需要修改setup.py
from setuptools import setup, find_packages
setup(packages = find_packages('src'), # 包含所有src中的包package_dir = {'':'src'}, # 告诉distutils包都在src下package_data = {# 任何包中含有.txt文件,都包含它'': ['*.txt'],# 包含demo包data文件夹中的 *.dat文件'demo': ['data/*.dat'],}
)
这样,在生成的egg中就包含了所需文件了。看看:
Archive: dist/demo-0.0.1-py2.7.eggLength Date Time Name-------- ---- ---- ----88 06-07-13 23:40 demo/__init__.py347 06-07-13 23:52 demo/__init__.pyc0 06-07-13 23:45 demo/aaa.txt0 06-07-13 23:46 demo/data/abc.dat0 06-07-13 23:46 demo/data/abcd.dat1 06-07-13 23:52 EGG-INFO/dependency_links.txt178 06-07-13 23:52 EGG-INFO/PKG-INFO157 06-07-13 23:52 EGG-INFO/SOURCES.txt5 06-07-13 23:52 EGG-INFO/top_level.txt1 06-07-13 23:52 EGG-INFO/zip-safe-------- -------777 10 files
description
- 项目的简短描述,一般一句话就好,会显示在 PyPI 上名字下端。
description='My first Python project'
对项目的完整描述,使用 long_description。如果此字符串是 rst 格式的,PyPI 会自动渲染成 HTML 显示。也可指定使用 markdown。
long_description=long_description,
long_description_content_type='text/x-rst'
url
- 通常为 GitHub上 的链接或者 readthedocs 的链接。。
url='https://github.com/pypa/sampleproject'
author
- 作者信息。
author='example',
author_email='example@example.com'
license
- 项目许可证。
license='MIT'
keywords
项目关键词列表。
keywords='sample setuptools development'
project_urls
项目相关额外连接,如代码仓库,文档地址等。
project_urls={'Documentation': 'https://packaging.python.org/tutorials/distributing-packages/','Funding': 'https://donate.pypi.org','Say Thanks!': 'http://saythanks.io/to/example','Source': 'https://github.com/pypa/sampleproject/','Tracker': 'https://github.com/pypa/sampleproject/issues',
}
install_requires
项目依赖的 Python 库,使用 pip 安装本项目时会自动检查和安装依赖。
install_requires=['pyyaml']
python_requires
指定项目依赖的 Python 版本。
python_requires='>=3'
上传 Wheel 到 PyPI
- Wheel 包可以自己使用和传输给其他人使用,但是维护更新不方便,而 PyPI 作为 Python 的 软件仓库,让所有人可以方便的上传和下载,以及管理三方库。
注册 PyPI 账号
登录 https://pypi.python.org/pypi,进入 Register 注册账号。
安装 twine
虽然 setuptools 支持使用 setup.py upload 上传包文件到 PyPI,但只支持 HTTP 而被新的 twine 取代。
同样的,需要先安装 twine:
pip install twine
使用 twine 上传
使用 upload:
twine upload dist/*
输入 username 和 password 即上传至 PyPI。如果不想每次输入账号密码,可以在家目录下创建 .pypirc 文件,内容如下:
[distutils]
index-servers =pypipypitest[pypi]
username:
password: [pypitest]
repository: https://test.pypi.org/legacy/
username:
password:
填上自己的账号密码即可,这里配置了官方的 pypi 和 pypitest,若要配置其他仓库,按格式添加。
回到 PyPI 主页即可看到上传的 firstApp。
PyPI 主页显示会有延迟,所以不能马上搜索到结果,pip search 也可能搜索不到,但已经可以使用 pip 安装。
以上就是 Python 打包和分发的全部内容,当然是最简单的功能。
PyPI 上传推荐配置
setup.py
-name
-version
-author
-author_email
-url
-packages
-description
-package_data/data_files
setup.cfg
MANIFEST.in
README.rst
LICENSE.txt
<项目>
一个完整的 setup.py 示例
from setuptools import setup, find_packageswith open('README.rst', 'r', encoding='utf-8') as rd:long_description = rd.read()setup(name="HelloWorld",version="0.1",packages=find_packages(),scripts=['say_hello.py'],# Project uses reStructuredText, so ensure that the docutils get# installed or upgraded on the target machineinstall_requires=['docutils>=0.3'],package_data={# If any package contains *.txt or *.rst files, include them:'': ['*.txt', '*.rst'],# And include any *.msg files found in the 'hello' package, too:'hello': ['*.msg'],},# metadata for upload to PyPIauthor="Me",author_email="me@example.com",description="This is an Example Package",long_description = long_description,license="PSF",keywords="hello world example examples",url="http://example.com/HelloWorld/", # project home page, if anyproject_urls={"Bug Tracker": "https://bugs.example.com/HelloWorld/","Documentation": "https://docs.example.com/HelloWorld/","Source Code": "https://code.example.com/HelloWorld/",}# could also include long_description, download_url, classifiers, etc.
)
这篇关于python打包:setuptools的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!