使用 setuptools 创建一个 python 可执行文件 [英] Create a python executable using setuptools

查看:33
本文介绍了使用 setuptools 创建一个 python 可执行文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小的 python 应用程序,我想将它做成一个可下载/可安装的 UNIX 类系统的可执行文件.我的印象是 setuptools 是实现这一目标的最佳方式,但不知何故,这似乎不是一项常见任务.

I have a small python application that I would like to make into a downloadable / installable executable for UNIX-like systems. I am under the impression that setuptools would be the best way to make this happen but somehow this doesn't seem to be a common task.

我的目录结构如下:

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.

The file which contains if __name__ == "__main__": is myappname.py. This file has a line at the top, import src.mainclassfile.

下载此文件后,我希望用户能够执行以下操作:

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

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

And then it will be an installed executable which they can invoke from anywhere on the command line with:

$ myappname arg1 arg2

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

The important parts of my setup.py are like:

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

然后在一个新的 shell 中:

And then in a new shell:

$ myapp.py

我收到No module named错误

推荐答案

这里的问题是你的包布局被破坏了.

The problem here is that your package layout is broken.

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

It happens to work in-place, at least in 2.x. Why? You're not accessing the package as myappname—but the same directory that is that package's directory is also the top-level script directory, so you end up getting any of its siblings via old-style relative import.

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

Once you install things, of course, you'll end up with the myappname package installed in your site-packages, and then a copy of myappname.py installed somewhere on your PATH, so relative import can't possibly work.

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

The right way to do this is to put your top-level scripts outside the package (or, ideally, into a bin directory).

此外,您的模块和脚本不应具有相同的名称.(您可以通过多种方式实现这一目标,但是……千万不要尝试.)

Also, your module and your script shouldn't have the same name. (There are ways you can make that work, but… just don't try it.)

例如:

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

当然,到目前为止,它所做的只是在就地模式下中断,与安装时中断的方式完全相同.但至少这让调试更容易,对吧?

Of course so far, all this makes it do is break in in-place mode the exact same way it breaks when installed. But at least that makes things easier to debug, right?

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

Anyway, your myscriptname.py then has to use an absolute import:

import myappname.src.mainclassfile

并且您的 setup.py 必须在正确的位置找到脚本:

And your setup.py has to find the script in the right place:

scripts=['myscriptname.py'],

最后,如果您需要 myscriptname.py 中的一些代码可以在模块内部以及脚本中访问,正确的做法是将其重构为两个文件——但是如果由于某种原因,这太难了,您可以随时编写包装脚本.

Finally, if you need some code from myscriptname.py to be accessible inside the module, as well as in the script, the right thing to do is to refactor it into two files—but if that's too difficult for some reason, you can always write a wrapper script.

参见整理文件和目录有关详细信息,请参阅 Hitchhiker's Guide to Packaging 中的结构和相关部分.

另请参阅 PEP 328 以了解有关绝对导入和相对导入的详细信息(但请记住,当它提到高达 Python 2.5"时,它的真正意思是高达 2.7",而从 2.6 开始"的意思是从 3.0 开始".

Also see PEP 328 for details on absolute vs. relative imports (but keep in mind that when it refers to "up to Python 2.5" it really means "up to 2.7", and "starting in 2.6" means "starting in 3.0".

一些包含通过 setup.py 以这种方式安装的脚本的包示例(通常还有 easy_installpip),参见ipythonbpythonmodulegraphpy2app,当然还有easy_installpip 自己.

For a few examples of packages that include scripts that get installed this way via setup.py (and, usually, easy_install and pip), see ipython, bpython, modulegraph, py2app, and of course easy_install and pip themselves.

这篇关于使用 setuptools 创建一个 python 可执行文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆