Python: исключая модули Pyinstaller
Я начал использовать Pyinstaller над Py2Exe. Однако я довольно быстро столкнулся с проблемой. Как я могу исключить модули, которые мне не нужны, и как просмотреть те, которые входят в один исполняемый файл?
Я могу удалить некоторые файлы pyd
и dll
из папки DLL в моей установке на Python, поэтому Pyinstaller не найдет и, следовательно, не включит их. Я действительно не хочу делать это со всеми модулями, так как это будет довольно сложно.
Я попытался отредактировать файл спецификации, который делает Pyinstaller.
a.binaries - [('ssl','pydoc',)],
Но размер файла остался прежним, поэтому я пришел к выводу, что это не сработало.
Итак, как я могу увидеть, какие модули содержат Pyinstaller, и как я могу исключить те, которые мне не нужны?
Ответы
Ответ 1
Просто подытожим варианты здесь, когда я их использую.
PyInstaller TOC - есть, как говорится в документации:
A TOC представляет собой список кортежей формы (имя, путь, TypeCode). На самом деле это упорядоченный набор, а не список. TOC не содержит дубликаты, где уникальность основана только на имени.
В других словах просто:
a_toc = [('uname1','/path/info','BINARY'),('uname2','/path/to','EXTENSION')...]
Итак, в вашем файле .spec - после того, как вы получите результаты анализа script, вы можете дополнительно изменить соответствующий TOC:
-
Для определенных файлов/модулей используйте операции разности (-) и пересечения (+) для изменения TOC. *
-
Для добавления/удаления списков файлов/модулей итерации по TOC и сравнения с кодом соответствия шаблонов.
(* В стороне, для разницы в работе, кажется, вы должны явно использовать TOC()
и отметить, что, поскольку это только имя, которое однозначно определяет элемент набора, вам нужно только указать, что - следовательно ('sqlite3', None, None)
и т.д.)
Иллюстративный пример (взятый из файла .spec) находится ниже, где - для лучшего или худшего - я удаляю все ссылки на scipy, IPython и zmq; удалить конкретные sqlite, tcl/tk и ssl.DLL; вставить отсутствующий opencv.DLL; и, наконец, удалите все папки данных, найденные отдельно от matplotlib...
Будет ли возникающий в результате Pyinstaller.exe работать, когда файл .pyc пытается загрузить ожидаемый .DLL является спорным :-/
# Manually remove entire packages...
a.binaries = [x for x in a.binaries if not x[0].startswith("scipy")]
a.binaries = [x for x in a.binaries if not x[0].startswith("IPython")]
a.binaries = [x for x in a.binaries if not x[0].startswith("zmq")]
# Target remove specific ones...
a.binaries = a.binaries - TOC([
('sqlite3.dll', None, None),
('tcl85.dll', None, None),
('tk85.dll', None, None),
('_sqlite3', None, None),
('_ssl', None, None),
('_tkinter', None, None)])
# Add a single missing dll...
a.binaries = a.binaries + [
('opencv_ffmpeg245_64.dll', 'C:\\Python27\\opencv_ffmpeg245_64.dll', 'BINARY')]
# Delete everything bar matplotlib data...
a.datas = [x for x in a.datas if
os.path.dirname(x[1]).startswith("C:\\Python27\\Lib\\site-packages\\matplotlib")]
Ответ 2
Вы можете манипулировать списками, создаваемыми классом Analysis, используя Python. Обратите внимание, что они находятся в формате TI PyInstaller.
a = Analysis(...)
...
# exclude anything from the Windows system dir
a.binaries = [x for x in a.binaries if not
os.path.dirname(x[1]).startswith("C:\\Windows\\system32")]
Ответ 3
Хотя могут быть даны лучшие решения, но есть еще один метод:
Вы можете использовать атрибут "--exclude-module" с командой "pyinstaller", но этот метод достаточно длинный, когда вам нужно исключить много модулей.
Чтобы упростить работу, вы можете написать файл пакетного скрипта со всеми библиотеками, которые стоит пропустить, и использовать его снова и снова.
Примерно так:
@echo off
pyinstaller --onefile a.py --exclude-module matplotlib ^
--exclude-module scipy ^
--exclude-module setuptools ^
--exclude-module hook ^
--exclude-module distutils ^
--exclude-module site ^
--exclude-module hooks ^
--exclude-module tornado ^
--exclude-module PIL ^
--exclude-module PyQt4 ^
--exclude-module PyQt5 ^
--exclude-module pydoc ^
--exclude-module pythoncom ^
--exclude-module pytz ^
--exclude-module pywintypes ^
--exclude-module sqlite3 ^
--exclude-module pyz ^
--exclude-module pandas ^
--exclude-module sklearn ^
--exclude-module scapy ^
--exclude-module scrapy ^
--exclude-module sympy ^
--exclude-module kivy ^
--exclude-module pyramid ^
--exclude-module opencv ^
--exclude-module tensorflow ^
--exclude-module pipenv ^
--exclude-module pattern ^
--exclude-module mechanize ^
--exclude-module beautifulsoup4 ^
--exclude-module requests ^
--exclude-module wxPython ^
--exclude-module pygi ^
--exclude-module pillow ^
--exclude-module pygame ^
--exclude-module pyglet ^
--exclude-module flask ^
--exclude-module django ^
--exclude-module pylint ^
--exclude-module pytube ^
--exclude-module odfpy ^
--exclude-module mccabe ^
--exclude-module pilkit ^
--exclude-module six ^
--exclude-module wrapt ^
--exclude-module astroid ^
--exclude-module isort
Или вы всегда можете использовать новую установку Python, просто измените путь новой установки Python во время установки.
Ответ 4
НАЙТИ ОТВЕТ СЕБЯ
Я видел много подобных вопросов, но никто не учит вас, как отлаживать самостоятельно.
Документ Pyinstaller может быть полезен для начинающих, но как только вам нужно больше...
лично я думаю, что документация pyinstaller не дружелюбна (слишком мало примеров) и не имеет обновлений.
Например, документ показывает версию pyinstaller 3.2. (3.5 доступно уже сейчас (2019/10/5))
Я хочу сказать, что вы должны найти ответ из исходного кода
НАЧАТЬ ПУТЬ
- создайте файл сценария (например, run_pyinstaller.py), как показано ниже:
# run_pyinstaller.py
from PyInstaller.__main__ import run
run()
перед запуском этого скрипта вы можете назначить параметры, например "--clean your.spec"
установите точку останова на {env_path}/Lib/site-packages/PyInstaller/building/build_main.py -> def build(...) ... -> exec(code, spec_namespace)
, как показано ниже:
примечание: Если вы не используете виртуальную среду, фактический путь должен быть {Python}/Lib/site-packages/PyInstaller/building/build_main.py
![enter image description here]()
- наконец, вы бежите сюда и нажимаете кнопку перехода в. Вы попадете в файл .spec
тогда вы можете посмотреть любые переменные, которые вас интересуют.
Кроме того, вы узнаете больше о pyinstaller.exe на самом деле делать.
например, вы узнаете, что класс оглавления наследуется от списка, и видите больше подробностей, чем документ из PyInstaller.building.datastruct
![enter image description here]()
в конце концов, вы можете использовать любой способ Python для установки a.binaries
и a.datas
, который вы действительно хотели
ОБЪЕДИНЕННЫЕ ФАЙЛЫ
from PyInstaller.building.datastruct import TOC, Tree
from PyInstaller.building.build_main import Analysis
from PyInstaller.building.api import EXE, PYZ, COLLECT, PKG, MERGE