Создание исполняемого файла python с помощью setuptools
у меня есть небольшое приложение 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__":
is myappname.py - ... Этот файл имеет строку вверху,import src.mainclassfile
.
когда это скачанный, я хотел бы, чтобы пользователь мог сделать что-то вроде:
$ python setup.py build
$ python setup.py install
и тогда это будет установленный исполняемый файл которые они могут вызывать из любой точки командной строки с помощью:
$ myappname arg1 arg2
важные части моего 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
1 ответов
проблема здесь в том, что ваш макет пакета сломан.
это происходит на месте, по крайней мере, в 2.х. Почему? Вы не получаете доступ к пакету как myappname
-но тот же каталог, который является каталогом этого пакета, также является каталогом скриптов верхнего уровня, поэтому вы в конечном итоге получаете любого из своих братьев и сестер через относительный импорт старого стиля.
как только вы установите вещи, конечно, вы в конечном итоге с myappname
пакет, установленный на вашем сайте-пакеты, а затем копия myappname.py
установлен где-то на вашем пути, поэтому относительный импорт не может работать.
правильный способ сделать это-поместить скрипты верхнего уровня вне пакета (или, в идеале, в ).
кроме того, ваш модуль и ваш скрипт не должны иметь одинаковое имя. (Есть способы заставить это работать, но ... просто не пытайтесь.)
так, например:
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
должны быть доступны внутри модуля, а также в скрипте, что нужно сделать, это переписать его в двух файлах-но если это слишком сложно для какой-то причине, вы всегда можете написать скрипт-обертку.
посмотреть организация структуры файлов и каталогов и связанные разделы в руководстве Автостопом по упаковке для получения более подробной информации.
см. Также PEP 328 подробнее об абсолютном и относительном импорте (но имейте в виду, что когда речь идет о "до Python 2.5", это действительно означает "до 2.7", а "начиная с 2.6" означает "начиная с 3.0".
для нескольких примеров пакеты, включающие скрипты, которые устанавливаются таким образом через setup.py
(и, как правило, easy_install
и pip
), см. ipython
, bpython
, modulegraph
, py2app
и конечно easy_install
и pip
сами.