使用Cython将Python打包成wheel文件
Wheel是Python的一种打包格式(.whl),目的是支持不需要编译的安装过程并且能够起到保护Python源码的作用。它实际上也是一种压缩文件,将.whl的后缀改为.zip即可可看到压缩包里面的内容。Wheel现在被认为是Python的二进制包的标准格式。
依赖:
- distutils
- setuptools
- Cython
- wheel
以上是在打包过程中需要用到的工具,可通过pip快速安装。
目录结构
将需要打包的Python工程按照上述目录结构组织,其中root为打包后的Module,__init__.py是实现import所必须的。接下来编写setup.py进行打包即可。
setup.py
Linux
from setuptools import setup
from setuptools.extension import Extension
from Cython.Build import cythonize
from Cython.Distutils import build_ext
setup(
name="MyModule" # 模块名称 import MyModule,
ext_modules=cythonize(
[
Extension("pkg1.*", ["root/pkg1/*.py"]),
Extension("pkg2.*", ["root/pkg2/*.py"]),
Extension("1.*", ["root/*.py"])
],
build_dir="build",
compiler_directives=dict(
always_allow_keywords=True
)),
cmdclass=dict(
build_ext=build_ext
),
packages=["pkg1", "pkg2"] # packages=[]时打包后的wheel文件中不含源码(.py)
)
python setup.py bdist_wheel
Windows
from setuptools import setup
from setuptools.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
from pathlib import Path
import shutil
class MyBuildExt(build_ext):
def run(self):
build_ext.run(self)
build_dir = Path(self.build_lib)
root_dir = Path(__file__).parent
target_dir = build_dir if not self.inplace else root_dir
self.copy_file(Path('root/pkg1') / '__init__.py', root_dir, target_dir)
self.copy_file(Path('root/pkg2') / '__init__.py', root_dir, target_dir)
self.copy_file(Path('root') / '__init__.py', root_dir, target_dir)
def copy_file(self, path, source_dir, destination_dir):
if not (source_dir / path).exists():
return
shutil.copyfile(str(source_dir / path), str(destination_dir / path))
setup(
name="MyModule",
ext_modules=cythonize(
[
Extension("pkg1.*", ["root/pkg1/*.py"]),
Extension("pkg2.*", ["root/pkg2/*.py"]),
Extension("1.*", ["root/*.py"])
],
build_dir="build",
compiler_directives=dict(
always_allow_keywords=True
)),
cmdclass=dict(
build_ext=MyBuildExt
),
packages=[],
)
注意:在Windows下打包时由于系统原因无法编译__init__.py,要解决这个问题,我们在构建项目的其余部分后从源码树中复制__init__.py文件,通过覆盖setup.py中的build_ext类。
pip install *.whl
相关文章
- Django基本命令
Django基本命令 打开linux终端直接在终端中输入以下命令即可。 新建一个django project 命令:django-admin.py startproject project-nam
- 17个新手常见Python运行时错误
17个新手常见Python运行时错误 当初学 Python 时,想要弄懂 Python 的错误信息的含义可能有点复杂。这里列出了常见的的一些让你程序 crash 的运行时错误。 当初学 Python
- Python+SQLite真的有用吗?
SQLite是个很简单的数据库,一个文件就可以搞定,存储上千万行的数据也没问题,图形界面程序有很多,管理很方便,用Python可以编程操作,也很简单,一切都似乎很完美。 我导入了几千万行的数据进SQL
- os各种各样的操作系统接口
这个模块提供了一种使用操作系统相关功能的移动方式。如果您只想读取或写入一个文件,请查看open(),如果您想要操作路径,请参见操作os.path模块,如果您想要读取命令行上所有文件中的所有行,请参阅f
- 通过webpy和nginx-with-fastcgi搭建web.py
这一节讲解的是如何使用Nginx和FastCGI搭建Web.py应用 环境依赖的软件包 Nginx 0.8.* or 0.7.* (需要包含fastcgi和rewrite模块)。 Webpy 0.3
随机推荐
- Django基本命令
Django基本命令 打开linux终端直接在终端中输入以下命令即可。 新建一个django project 命令:django-admin.py startproject project-nam
- 17个新手常见Python运行时错误
17个新手常见Python运行时错误 当初学 Python 时,想要弄懂 Python 的错误信息的含义可能有点复杂。这里列出了常见的的一些让你程序 crash 的运行时错误。 当初学 Python
- Python+SQLite真的有用吗?
SQLite是个很简单的数据库,一个文件就可以搞定,存储上千万行的数据也没问题,图形界面程序有很多,管理很方便,用Python可以编程操作,也很简单,一切都似乎很完美。 我导入了几千万行的数据进SQL
- os各种各样的操作系统接口
这个模块提供了一种使用操作系统相关功能的移动方式。如果您只想读取或写入一个文件,请查看open(),如果您想要操作路径,请参见操作os.path模块,如果您想要读取命令行上所有文件中的所有行,请参阅f
- 通过webpy和nginx-with-fastcgi搭建web.py
这一节讲解的是如何使用Nginx和FastCGI搭建Web.py应用 环境依赖的软件包 Nginx 0.8.* or 0.7.* (需要包含fastcgi和rewrite模块)。 Webpy 0.3