Python wheel包使用cython binary.so文件和配置、资源文件夹构建和安装

2024-06-26 12:58:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我的代码结构如下:

myMLCode 
│  
├── main.py
├── ML_lib
|   ├── __init__.py
│   └── core.py
|   └── set1
|       ├── __init__.py
│       └── mymod1.py
│       └── mymod2.py
|   └── set2
|       ├── __init__.py
│       └── mymod3.py
│       └── mymod4.py
├── config
│   ├── config1.yml
│   └── config2.yml
├── models
│   ├── model1.h5
│   └── model2.h5
├── setup.py 

我想做的是使用整个包中的cythonized代码生成一个轮子文件,并能够无缝地运行代码

期望与python main.py一起运行 另外,我想编辑配置文件,不时更新模型文件,并继续使用该软件包

到目前为止,我所做的是使用以下setup.py文件:

from Cython.Distutils import build_ext
from Cython.Build import cythonize
from setuptools.extension import Extension
from setuptools.command.build_py import build_py as build_py_orig
from pathlib import Path
from setuptools import find_packages, setup, Command
import os
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('ML_lib/__init__.py', root_dir, target_dir)
        self.copy_file('ML_lib/set1/__init__.py', root_dir, target_dir)
        self.copy_file('Ml_lib/set2/__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))

extensions = [
    Extension("core", ["core.py"]),
    Extension("ML_lib.set1.*", ["ML_lib/set2/*.py"]),
    Extension("ML_lib.set2.*", ["ML_lib/set2/*.py"]),
    Extension("ML_lib.*", ["ML_lib/*.py"]),
]

setup(
    name="myMLCode",
    version="0.0.1",
    author="myself",
    description="This is compiled ML code",
    ext_modules=cythonize(
        extensions,
        build_dir="build",
        compiler_directives=dict(
        always_allow_keywords=True
        )),
    data_files=[
        ('config',['config/config1.yml']),
        ('config',['config/config2.yml']),
        ('models',['models/model1.h5']),
        ('models',['models/model2h5']),
    ],
    cmdclass={
        'build_ext': MyBuildExt
    },
    entry_points={
    },
)

这将生成一个包含以下内容的控制盘文件:

myMLCode-0.0.1-cp37-cp37m-linux_x86_64.whl
------------------------------------------
 main.cpython-37m-x86_64-linux-gnu.so'
'ML_lib/__init__.cpython-37m-x86_64-linux-gnu.so'
'ML_lib/__init__.py'
'ML_lib/core.cpython-37m-x86_64-linux-gnu.so'
'ML_lib/set1/mymod1.cpython-37m-x86_64-linux-gnu.so'
'ML_lib/set1/mymod2.cpython-37m-x86_64-linux-gnu.so'
'ML_lib/set1/__init__.cpython-37m-x86_64-linux-gnu.so'
'ML_lib/set1/__init__.py'
'ML_lib/set2/mymod3.cpython-37m-x86_64-linux-gnu.so'
'ML_lib/set2/mymod4.cpython-37m-x86_64-linux-gnu.so'
'ML_lib/set2/__init__.cpython-37m-x86_64-linux-gnu.so'
'ML_lib/set2/__init__.py'
'myMLCode-0.0.1.data/data/config/config1.yml'
'myMLCode-0.0.1.data/data/config/config2.yml'
'myMLCode-0.0.1.data/data/models/model1.h5'
'myMLCode-0.0.1.data/data/models/model2.h5'
'myMLCode-0.0.1.dist-info/METADATA'
'myMLCode-0.0.1.dist-info/WHEEL'
'myMLCode-0.0.1.dist-info/top_level.txt'
'myMLCode-0.0.1.dist-info/RECORD'

然后我用pip安装了这个轮子文件。 我列出了库来检查它是否已安装,然后打开了一个python3.7终端来使用它,但是我得到了一个导入错误

[user@userhome~]$ pip3.7 list
Package            Version
------------------ -------
appdirs            1.4.4
distlib            0.3.1
filelock           3.0.12
importlib-metadata 4.0.1
pip                20.1.1
setuptools         47.1.0
six                1.15.0
typing-extensions  3.7.4.3
virtualenv         20.4.4
myMLCode           0.0.1
zipp               3.4.1
[user@userhome ~]$ python3.7
Python 3.7.9 (default, Apr 27 2021, 07:49:13)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import myMLCode
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>

ModuleNotFoundError: No module named 'myMLCode'

我尝试解压包,并尝试直接使用.so文件运行代码。除了配置和模型文件引用之外,它工作得很好。该包将文件放在myMLCode.data.data.config和myMLCode.data.data.models中。我做了一次黑客攻击,更改了源代码中的所有相关路径,以引用这个新位置。它可以处理这个问题,但这不是一个优雅的解决方案,因为普通python代码停止工作,因为它不知道这些新文件夹

任何指示都会非常有用


Tags: pygnuimportbuilddatasoinitlinux