【发布时间】:2021-04-22 15:35:13
【问题描述】:
我想使用 python 3.6(64 位)从 x64 Native Tools Command Prompt for VS 2019 中将 python3 包编译成可分发的二进制形式(无源代码)。但是,我在指定包应包含的文件的正确路径时遇到问题。 site-packages 目录中生成的文件夹结构都是错误的,而不是我对源文件夹结构和setup.py 的期望。
在我看来,顶级包中的模块的处理方式不同,但我不知道为什么会这样。
我的目录结构如下:
.
├── hello
│ ├── hello1.py
│ ├── hello2.py
│ └── __init__.py
│ bye
│ ├── bye1.py
│ ├── bye2.py
│ └── __init__.py
├── setup.py
└── test
└── test.py
hello 包中的__init__.py 包含from . import hello1, hello2, bye 行,bye 包中的__init__.py 包含from . import bye1, bye2 行。
hello1.py 和 hello2.py 分别包含函数 print_hello 和 print_hello2,bye1.py 和 bye2.py 函数 print_bye 和 print_bye2。
为了完成编译,我设置了以下setup.py:
from setuptools import Extension, setup, find_packages
from Cython.Build import cythonize
setup(name='hello',
version='0.3',
url='https://someurl',
license='somelicense',
author='Pepper Wutz',
author_email='wutz@gmail.com',
description='Prints "Hello World"',
ext_modules=cythonize([Extension("hello", ["hello/*.py"]), Extension("hello.bye", ["hello/bye/*.py"]), language_level=3),
zip_safe=False)
当我从顶层文件夹运行这个模块时:
py -3.6 setup.py bdist_wheel
然后安装它(从测试子文件夹中):
py -3.6 -m pip install dist/hello-0.3-cp36-cp36m-win_amd64.whl
我得到以下输出文件:
Verzeichnis von C:\Users\User\AppData\Roaming\Python\Python36\site-packages
18.01.2021 17:32 <DIR> hello
18.01.2021 17:32 <DIR> hello-0.3.dist-info
18.01.2021 17:32 20.480 hello.cp36-win_amd64.pyd
1 Datei(en), 20.480 Bytes
2 Verzeichnis(se), 15.070.900.224 Bytes frei
Verzeichnis von C:\Users\User\AppData\Roaming\Python\Python36\site-packages\hello
18.01.2021 17:32 <DIR> .
18.01.2021 17:32 <DIR> ..
18.01.2021 17:32 20.480 bye.cp36-win_amd64.pyd
1 Datei(en), 20.480 Bytes
2 Verzeichnis(se), 15.070.142.464 Bytes frei
显然,site-packages 中 hello 包的文件夹结构与我原来的文件夹结构有很大不同。例如,hello.cp36-win_amd64.pyd 被放入顶级作用域,bye 包被放入 hello 子目录和子作用域。 hello1 和 hello2 模块没有放在 hello 包中,而只放在了 bye 包中。这完全弄乱了从解释器运行代码时起作用的相对导入:
C:\Users\User\source\repos\cython_tests\test>py -3.6 -c "import hello; print(dir(hello))"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "hello\__init__.py", line 1, in init hello
ImportError: attempted relative import with no known parent package
可疑的是,包含 hello 源的 hello 文件夹只有 __init__.c 文件,但没有 hello1.c 和 hello2.c。 hello\bye 文件夹也是如此。
18.01.2021 17:27 <DIR> .
18.01.2021 17:27 <DIR> ..
18.01.2021 17:27 <DIR> bye
18.01.2021 10:58 147 hello1.py
15.01.2021 20:11 150 hello2.py
18.01.2021 17:27 103.044 __init__.c
18.01.2021 17:20 35 __init__.py
4 Datei(en), 103.376 Bytes
3 Verzeichnis(se), 15.068.041.216 Bytes frei
我只是迷失在编写适当的setup.py,尤其是指定ext_modules。我不明白我做错了什么。也许其他人看到了。
我想要获得的是一个二进制包,我可以使用import hello 导入它,我可以从中调用hello1 和hello2 中的函数,如下所示:hello.hello1.print_hello()、hello.hello2.print_hello2() 以及hello.bye.bye1.print_bye()、hello.bye.bye2.print_bye2()。
【问题讨论】:
-
我曾建议 this question 重复,但仔细一看,我认为这不是您想要的。
-
对于这个问题以及由此引起的刺激感到非常抱歉。今天,我在这个编译问题上投入了几个小时,向前走了两步,向后走,以此类推。 @DavidW:我不介意将每个 py 模块编译为单个 .so(或 .pyd),只要维护包层次结构并且该过程不会向站点包的根目录发送垃圾邮件。
标签: python-3.x compilation cython setuptools binaryfiles