构建引用 .PYD 的 Python 包/模块的正确方法是啥?

Posted

技术标签:

【中文标题】构建引用 .PYD 的 Python 包/模块的正确方法是啥?【英文标题】:What is the proper way to construct a Python package/module referencing a .PYD?构建引用 .PYD 的 Python 包/模块的正确方法是什么? 【发布时间】:2015-01-21 17:59:00 【问题描述】:

我是 Python 世界的新手,现在我发现自己正在尝试学习如何正确创建 Python 包或模块。我还有几个必须满足的要求。

我有一个从 C++ 编译的核心原生 DLL(我们将其命名为 MyCore.dll)。该 DLL 必须部署到特定的安装位置,因为它是产品的核心组件(我们会说 ProgramFiles\MyProduct)。

我使用 SWIG 为 MyCore.dll 生成 Python 绑定。它生成了 2 个文件:_MyCoreBindings.pyd(本质上是一个引用 MyCore.dll 的 DLL)和 MyCoreBindings.py(加载 _MyCoreBindings.pyd 并为其提供 Python API)。

最后,我有一个仅包含导入的 Python 脚本 (MyProduct.py),因为我的产品必须在 Python 中以 MyProduct.SDK 的名称导入:

import MyCoreBindings as SDK

因此,我希望用户的 Python 脚本能够像这样访问它:

import MyProduct.SDK

按依赖顺序排列的文件摘要:

ProgramFiles\MyProduct\MyCore.dll _MyCoreBindings.pyd MyCoreBindings.py MyProduct.py(我不确定我是否需要这个)

我还了解到 Python 包的格式涉及一些模仿导入路径的目录结构,并且可能包含 setup.py__init__.py ,但是我读过的所有材料都没有明确说明每个文件中必须包含哪些内容,以及在什么情况下需要它们。我绝对不清楚这个目录结构可能放在哪里。

【问题讨论】:

【参考方案1】:

如果您希望 Python 能够导入您的模块,那么您有两种选择:

将模块安装到 Python 的 site-packages 文件夹。 修改 Python 搜索要导入的模块/包的路径。您可以通过 *.pth 文件或使用 Python 的 sys 模块(即 sys.path.append(/some/path) )修改路径来做到这一点

您使用setup.py 来安装您的包和/或创建鸡蛋/***等。有关有用的提示,请参阅以下内容:

https://docs.python.org/2/distutils/setupscript.html https://pythonhosted.org/an_example_pypi_project/setuptools.html

您可以在模块旁边的文件夹中使用_init__.py 创建一个包:

- MyProduct
  - __init__.py
  - MyCoreBindings.py
  - _MyCoreBindings.pyd

_init__.py 文件可以为空。这基本上允许您将文件夹导入为MyProduct

import MyProduct

MyProduct.MyCoreBindings

from MyProduct import MyCoreBindings as SDK

如果您在根文件夹中使用__init__.py,则不需要MyProduct.py。我希望这一切都有意义。

【讨论】:

在您的方案中,MyCoreBindings.pyd 与它所链接的 MyCore.dll 不相邻。 _init__.py 中是否有任何方法可以确保 ProgramFiles\MyProduct\MyCore.dll_MyCoreBindings.pyd 时出现在 dll 搜索路径中加载了吗? 您当然可以将 dll 和其他所有内容放在同一个文件夹中。您只需要确保更新 Python 的搜索路径,这就是 sys.path.append*.pth 文件的用途

以上是关于构建引用 .PYD 的 Python 包/模块的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Conda Cython 构建 PYD/SO 文件

Python程序加密打包

在Python软件包中包含* .pyd文件怎么打包保存?

在 setup.py 文件中直接包含一个 pyd

运行 python pyd 模块的几个独立实例

Python 模块引用和编译