Немного про py2exe

    Есть такое приложение. Называется py2exe. Оно позволяет упаковать, сконвертировать программу на python в exe файл (ну, точнее, exe и еще кучку других). Зачем оно все надо? Ну, далеко не у всех пользователей windows установлен интерпретатор python с нужными библиотеками. А вот упакованная программа в идеале должна запуститься на любой windows-машине.


    Установка


    К сожалению, py2exe не поддерживает третью версию питона.
    Скачать py2exe можно на SourceForge.
    Если у вас стоит python (а он у вас наверняка стоит), проблем с установкой возникнуть не должно. Ставится в директорию python.

    Конвертация


    Теперь начинается самое интересное. В директории, где лежит Ваша программа на python, надо создать файл setup.py со следующим содержанием
    Copy Source | Copy HTML
    1. from distutils.core import setup
    2. import py2exe
    3.  
    4. setup(
    5.     windows=[{"script":"main.py"}],
    6.     options={"py2exe": {"includes":["sip"]}}
    7. )
    Где main.py имя Вашего скрипта.

    Далее запускаем упаковку командой:
    setup.py py2exe

    Да-да, именно так.

    Смотрим, что у нас получилось. Две папки.
    build — служебная, можно сразу снести.
    dist — собственно, в ней и лежит наша программа.

    Как было сказанно выше, это не один файлик:
    • main.exe — программа
    • pythonXX.dll — интерпретатор python'a
    • library.zip — архив со скомпилированными исходниками (всего, кроме собственно программы, как я понимаю)
    • .pyd — модули python, которые импортирует программа
    • .dll — библиотеки, оказавшиеся необходимыми
    • и еще файлы по мелочи, ниже будет сказано еще

    Неужели все так просто? Неправда;)

    Сложности


    Скорее всего возникнут какие-то проблемы.

    Например, пути к файлам. Не следует использовать относительные пути. Они ведут неведомо куда. Лучше использовать абсолютные.
    Как его узнать? в интернете есть решение, функция module_path.
    Copy Source | Copy HTML
    1. import os, sys
    2.  
    3. def module_path():
    4.     if hasattr(sys, "frozen"):
    5.         return os.path.dirname(
    6.             unicode(sys.executable, sys.getfilesystemencoding( ))
    7.         )
    8.     return os.path.dirname(unicode(__file__, sys.getfilesystemencoding( )))

    Или приложение наотрез откажется запускаться (возможно, не у Вас, а у кого-то еще). Из-за отсутствие библиотек Visual Studio.
    В качестве решения проблемы можно установить их на компьютер (но это же не наш метод) или кинуть dll и файл манифеста в папку с программой.
    msvcr90.dll и Microsoft.VC90.CRT.manifest (не знаю как это лицензируется и выкладывать не буду)
    Где их взять? Для меня самым простым было переустановить python (все остальное осталось на месте) в режиме «только для меня». И искомые файлы оказались в папке с python.

    Целью топика не являлось раскрыть всех особенностей py2exe. Здесь находится туториал, а тут некоторые советы и трюки.

    Размер


    В силу некоторых особенностей, приложение может получиться ужасающего размера. Но с этим можно и нужно бороться. Идеи подсказал kAIST (ну, кроме upx’а =р)

    1. Самое действенное. Сжать библиотеки upx’ом. Консольное приложение. Работает элементарно. На вход передается файл, оно его сжимает. Для моей игры реверси размер уменьшился в ~3 раза.
    2. Удалить unicodedata.pyd, bz2.pyd, select.pyd, w9xpopen.exe. Веса немного, но, как минимум, в проекте станет меньше файлов
    3. Если в setup.py указать опцию optimize:2, то модули будут компилироваться в .pyo (python optimized code), а не в .pyc (python compiler script). Это не дает большого эффекта, но кто знает, может Вам повезет)
    4. И наконец, можно подчистить library.zip от неиспользованных модулей и кодировок. Только аккуратно.

    Вывод


    Ну вот, кажется, и все. Мы добились, чего хотели. Да, приложение получилось солидного размера (это вам не C++, например), зато на нашем любимом Python:)
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 35

    • НЛО прилетело и опубликовало эту надпись здесь
        +4
        забыли упомянуть что эта славная приблуда работает только со второй версией python. ну может и с первой, но не суть важно. главное что не с третьей, вот)
          0
          optimize:2 не даст большого эффекта, но вырежет docstring`и; для некоторых приложений они необходимы. это не самое удачное решение, но я иногда хранил в них какие-то важные для программы данные.
            +1
            > msvcr90.dll и Microsoft.VC90.CRT.manifest [...] Где их взять?

            Можно проще: поискать в гугле. :) Существует достаточно много сайтов с коллекциями разных DLL-файлов.

            Непонятно, почему py2exe использует библиотеку Visual Studio установленной версии, а не древнюю (шестой версии, вроде) msvcr.dll, которая есть везде?
              0
              Официальная сборка Python 2.6 — с msvcr90.dll. В принципе, можно собрать его и VC6, но я бы не стал рисковать — слишком неоттестировано.
                0
                Я не могу понять часть комментария про риск, т.к мало имел дело с компиляторами. Но разве не компилятор Visual Studio дёргает эту DLLку? Он. Следовательно, какая разница чем собран питон?

                Поэтому как может быть неоттестировано?
                  0
                  py2exe ничего не компилирует, а создаёт стаб, который прописывает пути к питоновским модулям и вызывает настоящий интерпретатор из pythonXX.dll. Естественно, если питон собран VC9, то pythonXX.dll зависит от msvcrt90.dll
                    0
                    Я и не писал, что py2exe чего-то компилирует.

                    По поводу комментария ниже (про риски). Суть понятна: глюков может и не быть, но мало ли чё. :)
                    0
                    А насчет риска — слишком мало людей используют питон, собранный VC6, так что вполне вероятны какие-нибудь грабли из-за багов компилятора, другого поведения рантайма или ещё по какой причине.
                0
                Ни разу не встречались программы написанные на Python, упакованые в ехе и распространяемые таким образом. Сам, когда изучал Python, пробовал эту фишку, но так, ради любопытства, не более… Хотя да, если программа написана для себя и планируется её запуск на машине без интерпретатора то это, наверное, выход..., но для массового распространения вариант сомнительный…
                  0
                  Я такую писал. Неудобно, архив большой, приходилось рядом с exe доп. библиотеки по полметра класть. Но люди всё-равно качали и пользовались, варезники всё-равно распространяли. Размер архива был где-то 5-8 метров. Пять в начале и восемь — у последней выпущенной версии. Хотя программка сама по себе была малюсенькой.

                  Меня только единожды упрекнули и не в весе архива, а в языке: мол, зачем на питоне, если можно было на дельфи (кажется, его предлагали).
                  • НЛО прилетело и опубликовало эту надпись здесь
                      +1
                      Например, Google App Engine SDK для Windows собран с помощью py2exe.
                        +2
                        наш софт писаный на питоне пакуется так. а еще и InnoSetup завернут. Очень удобно. Простые люди даже не догадываются, что это софт на питоне писан.
                          0
                          bittorrent тоже py2exe пакуется для инасталляторов под win32
                          +7
                          А PyInstaller умеет все то же самое, но кроме того упаковывает манифесты и msvcr автоматически (с патчем на него), плюс поддерживает всякие иконки для exe файла, из коробки — UPX и не создает файлов для stdin/stdout, если отключен консольный режим (клиентов лишние файлы всегда смущают).

                          Жаль, что про него мало кто говорит, а по мне — так гораздо более достойный вариант.
                            0
                            Сейчас посмотрел, согласен, pyinstaller куда проще и все получилось с первого раза. Но размер exe получился 10,5 мб против 8,6 у py2exe (для приложения использующено py2exe). Однако, похоже я все же буду использовать PyInstaller…
                              +1
                              Там есть тулза ArchiveViewer.py, делаете ей «ArchiveViewer.py ВашФайл.exe», и смотрите какой лишней хрени оно туда запихнуло.

                              Потом в файле проекта я обычно пишу:

                              a = Analysis(

                              ...........

                              excludes = [
                              'win32ui',
                              'win32api',
                              '_ssl',
                              'bz2',
                              'Microsoft.VC90.CRT\\msvcm90.dll',
                              ]
                              )


                              Без этих либ оно обычно всегда работает, размер получается около 6Мб.

                              Если с PyQt, то еще есть такой финт ушами, чтобы он туда не пропихнул кучу ненужных плагинов для всего подряд:

                              bad_files = []
                              for name,path,type in a.datas:
                              if name.startswith('qt4_plugins'):
                              bad_files.append((name,path,type))
                              a.datas -= bad_files


                              Сборка, включающая в себя PyQt (QtCore+QtGui) получается обычно 9-10.5 Мб.
                                0
                                Удалось сжать до 9,5 мб. Спасибо, добрый человек)
                                0
                                для приложения использующено py2exe
                                pyqt4, конечно же :-[
                                  +1
                                  С PyQt да, меньше 10мб трудно сделать. Хотел для этого перекомпилить PyQt через VS (по дефолту скачивается MinGW версия), чтобы сделать его меньше по объему и выкинуть mingw-ные либы. Помню когда на Qt писал, то VS-ные сборки были прям чуть ли не в 2 раза легче по размеру.

                                  Но пока лень… Да и какая, впрочем, разница, ну будет 8 метров вместо 10 — при нынешних объемах жестких дисков и ширине каналов это давно уже мало имеет значения для таких продуктов. А там, где значение имеет — нечего на питоне писать, там с++ есть и даже голый си…
                                0
                                Таааак. Не все так радужно оказалось. На другом компьютере (там, как минимум, не установлены библиотеки студии) приложение отказывается запускаться.
                                Error loading python DLL: path/python26.dll (error code 14001)

                                Собирал так:
                                Makespec.py -F -w -X main.py
                                Build.py ./main/main.spec

                                Не сталкивались?
                                  0
                                  Надо патч для поддержки питона 2.6 с его манифестами. Брать отсюда, там есть список, возьмите посвежей. Накатить надо поверх той ревизии для которой предназначен патч.

                                  Один раз сделаете себе патченую версию, дальше можно пользоваться ей и горя не знать. У меня полугодовой давности вот пользуюсь постоянно — и ничего, проблем не испытываю.
                                    0
                                    Слил к себе 771 ревизию PyInstaller. Накатил последний патч (pyinstaller-trunk-r768-py26-win-tweaks-20100210.patch) для 768 ревизии. Пересобрал приложение. Ошибка та же =/
                                      +1
                                      Очевидно что надо было слить 768 ревизию ;-)
                                +1
                                Сжатие upx'ом нужно разве что для того, чтобы это дело занимало мало место на диске. Аналогичный эффект достигается при создании инсталлятора.
                                В памяти же, размер будет исходный.

                                Как вариант можно создать минимальную необходимую для нашей программы сборку питона.
                                  0
                                  PyInstaller автоматически отслеживает зависимости всех файлов (даже бинарных) и включает только их. Конечно, это делает сборку проекта не моментальной, зато результат хороший.
                                  +1
                                  Для третьего питона конечно это не заработает?
                                    0
                                    Угу :( Надо дописать в топик.
                                    +1
                                    «Ну, далеко не у пользователей „

                                    Наверно правильно: “Ну, далеко не у всех пользователей „
                                      0
                                      Fixed.
                                      0
                                      А кто такой Веся Неманого? oO
                                        0
                                        Оу. Интересный вопрос.
                                        0
                                        А как указать путь для каталога build? C dist_dir все понятно, а вот мусорный build приходится сносить батником, хотел бы его куда-нибудь в %temp% засунуть.
                                          0
                                          Он не мусорный, он помогает когда много раз ребилдишь… Типа не баг, а фича;)

                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                        Самое читаемое