使用setuptools创建python可执行文件

2024-05-29 04:23:23 发布

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

我有一个小的python应用程序,我想让它成为一个可下载/可安装的可执行文件,用于类UNIX系统。在我的印象中,setuptools是实现这一点的最佳方法,但不知何故,这似乎不是一项常见的任务。

我的目录结构如下:

myappname/
|-- setup.py
|-- myappname/
|   |-- __init__.py
|   |-- myappname.py
|   |-- src/
|      |-- __init__.py
|      |-- mainclassfile.py
|      |-- morepython/
|         |-- __init__.py
|         |-- extrapython1.py
|         |-- extrapython2.py

包含if __name__ == "__main__":的文件是myappname.py。这个文件的顶部有一行,import src.mainclassfile

下载后,我希望用户能够执行如下操作:

$ python setup.py build
$ python setup.py install

然后它将是一个已安装的可执行文件,它们可以从命令行的任何位置调用:

$ myappname arg1 arg2

my setup.py的重要部分如下:

from setuptools import setup, find_packages
setup(
  name='code2flow',
  scripts=['myappname/myappname.py'],
  package_dir={'myappname': 'myappname'},
  packages=find_packages(),
  )

当前状态

通过运行:

$ sudo python setup.py install

然后在一个新的外壳中:

$ myapp.py

我收到一个No module named错误


Tags: install文件namepyimportsrc应用程序可执行文件
1条回答
网友
1楼 · 发布于 2024-05-29 04:23:23

这里的问题是您的包布局已损坏。

它碰巧在适当的位置工作,至少在2.x.为什么?您不是以myappname的身份访问包的,但是与包的目录相同的目录也是顶级脚本目录,因此您最终会通过旧样式的相对导入获取其任何同级目录。

当然,一旦您安装了东西,您最终将在站点包中安装myappname包,然后在路径上的某个位置安装myappname.py的副本,因此相对导入可能无法工作。

正确的方法是将顶级脚本放在包外(或者,理想情况下,放在bin目录中)。

另外,模块和脚本不应该同名。(你有办法做到这一点,但是……不要尝试。)

例如:

myappname/
|-- setup.py
|-- myscriptname.py
|-- myappname/
|   |-- __init__.py
|   |-- src/
|      |-- __init__.py
|      |-- mainclassfile.py

当然,到目前为止,它所做的一切都是以与安装时完全相同的方式插入到位模式。但至少这会让调试变得更容易,对吧?

无论如何,您的myscriptname.py必须使用绝对导入:

import myappname.src.mainclassfile

你的setup.py必须在正确的地方找到脚本:

scripts=['myscriptname.py'],

最后,如果您需要myscriptname.py中的一些代码才能在模块内部和脚本中访问,那么正确的做法是将其重构为两个文件,但是如果由于某些原因这太困难,则可以始终编写包装器脚本。

有关更多详细信息,请参见《搭便车者包装指南》中的Arranging your file and directory structure和相关章节。

有关绝对导入和相对导入的详细信息,请参见PEP 328(但请记住,当它提到“高达Python 2.5”时,实际上意味着“高达2.7”,“从2.6开始”意味着“从3.0开始”。

有关通过setup.py(通常是easy_installpip)安装脚本的包的一些示例,请参见ipythonbpythonmodulegraphpy2app,当然还有easy_installpip本身。

相关问题 更多 >

    热门问题