Вспомните: в уроках 3.1–3.3 утилита итогов расходов получила параметры запуска, а сортировщик «Загрузок» — окно с кнопками и файл настроек settings.json. Но запустить их по-прежнему может только тот, у кого стоит Python и кто знает команду python sorter.py. Коллеге из бухгалтерии нужна иконка, по которой щёлкают дважды. В этом уроке делаем из скрипта exe и разбираемся, что именно отдавать и где программе искать свои файлы.
🎯 После урока сможете: поставить PyInstaller, собрать свою утилиту в папку (--onedir) и в один файл (--onefile), убрать чёрное окно консоли у программы с окном (--windowed), найти готовый exe в dist, решить, что именно отправить коллеге, и написать код, который находит settings.json рядом с exe, откуда бы его ни запустили.
Урок проверен сборкой: PyInstaller 6.22.3, Python 3.14, Windows 10. Все выводы и деревья папок ниже — из этого прогона, только имя пользователя в путях заменено на
ученик. Номера в начале строк журнала (миллисекунды от старта) и имя временной папки_MEI…у вас будут другими.
Что делает PyInstaller и чего он не умеет
PyInstaller не переводит программу в машинный код. Он упаковывает: берёт ваш скрипт, находит все модули, которые тот импортирует, и складывает рядом копию интерпретатора Python (python314.dll) и нужные библиотеки. Спереди ставится маленький запускающий exe — загрузчик. Двойной щелчок по нему запускает Python из этой копии, и ваш скрипт работает на машине, где Python не установлен.
Три честные оговорки, которые стоит знать до первой сборки:
- Сборка — под свою систему. В документации прямо сказано: PyInstaller не кросс-компилятор. Exe для Windows собирают на Windows, программу для macOS — на Mac, для Linux — на Linux. Результат привязан и к ОС, и к версии Python, на которой собирали.
- Антивирус может ругаться. Незнакомый exe без цифровой подписи, который при запуске распаковывает файлы во временную папку, — ровно то, что антивирусы проверяют с подозрением. Бывает, что Защитник Windows или другой антивирус блокирует свежесобранную программу или помещает её в карантин. Это не значит, что в ней вирус; скажите коллеге заранее и отправляйте исходник
.pyрядом, чтобы было видно, что внутри. - Размер. Даже скрипт в 20 строк тянет за собой интерпретатор: папка сборки ниже весит около 20 МБ, один файл с окном Tkinter — около 12 МБ.

Проверьте себя
Контрольный вопрос. Что делает PyInstaller со скриптом itogi.py?
Подсказка: Вспомните, какой файл из _internal отвечает за сам язык Python и зачем он лежит рядом с exe.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Вы работаете на Windows. Коллеге с MacBook нужна ваша утилита. Как получить версию для macOS?
Подсказка: Перечитайте первую оговорку: к чему привязан результат сборки?
Онлайн-проверка ответа появится позже
Установка и первая сборка
PyInstaller — обычный пакет, ставится через pip. Удобнее всего ставить его в отдельное виртуальное окружение проекта — папку со своей копией Python и своими пакетами: тогда в exe не попадут лишние библиотеки из системы. В папке с утилитой в терминале:
python -m venv venv
venv\Scripts\activate
python -m pip install pyinstaller
python -m PyInstaller --version
Вторая строка включает окружение (на macOS и Linux — source venv/bin/activate), после неё в начале строки терминала появится (venv). Последняя команда выводит версию — у нас 6.22.3. Запись python -m PyInstaller (с большими P и I) работает, даже если короткая команда pyinstaller не нашлась в PATH.
Собираем утилиту итогов из прошлых уроков. Возьмём короткую версию, которая читает лимит расходов из settings.json, — почему в ней функция app_dir(), разберём в разделе про файлы рядом, пока просто соберём:
import json
import sys
from pathlib import Path
def app_dir():
if getattr(sys, "frozen", False):
return Path(sys.executable).parent
return Path(__file__).parent
settings_path = app_dir() / "settings.json"
if settings_path.exists():
settings = json.loads(settings_path.read_text(encoding="utf-8"))
else:
settings = {"limit": 30000}
print("Папка программы:", app_dir())
print("frozen:", getattr(sys, "frozen", False))
print("Лимит:", settings["limit"])
python -m PyInstaller itogi.py
Сборка идёт 15–30 секунд и печатает несколько десятков строк INFO. Важны первые и последняя:
> python -m PyInstaller itogi.py
450 INFO: PyInstaller: 6.22.3, contrib hooks: 2026.8
451 INFO: Python: 3.14.3
627 INFO: Platform: Windows-10-10.0.19045-SP0
628 INFO: wrote C:\Users\ученик\Desktop\itogi\itogi.spec
...
17759 INFO: checking COLLECT
17760 INFO: Building COLLECT COLLECT-00.toc
17905 INFO: Building COLLECT COLLECT-00.toc completed successfully.
17907 INFO: Build complete! The results are available in: C:\Users\ученик\Desktop\itogi\dist
В начале — версии PyInstaller, Python и системы, под которую идёт сборка. Строка wrote … itogi.spec — PyInstaller записал файл настроек сборки. Последняя строка Build complete! — сборка удалась и показывает, в какой папке результат. Если сборка упала, в последних строках будет ERROR с причиной.
Проверьте себя
Задание. Ниже — последние строки журнала сборки. Как называется папка, в которой лежит готовая программа? Введите только имя последней папки из пути, без слешей.
17905 INFO: Building COLLECT COLLECT-00.toc completed successfully.
17907 INFO: Build complete! The results are available in: D:\Projects\sorter\dist
Подсказка: Найдите строку, где PyInstaller сообщает, что сборка закончена, и прочитайте путь в её конце.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Задание. В начале журнала сборки есть строка ниже. Под какую операционную систему собрана программа? Введите одно слово: Windows, Linux или macOS.
627 INFO: Platform: Linux-6.8.0-45-generic-x86_64-with-glibc2.39
Подсказка: В какой строке журнала PyInstaller сообщает платформу? Название системы стоит перед первым дефисом.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Что появилось в папке: build, dist и .spec
После сборки рядом со скриптом три новых объекта:
itogi\
├── itogi.py
├── itogi.spec
├── build\
│ └── itogi\ (служебные файлы сборки, warn-itogi.txt)
└── dist\
└── itogi\
├── itogi.exe
└── _internal\ (53 файла: python314.dll, base_library.zip, *.pyd, *.dll)
dist\itogi\— готовая программа. Именно эту папку отдают. Внутриitogi.exeи папка_internal, где лежатpython314.dll, архив стандартной библиотекиbase_library.zipи модули с расширениями.pydи.dll.build\— черновики сборки. Отдавать не нужно, можно удалить. Полезен в нём один файл:build\itogi\warn-itogi.txt— список модулей, которые PyInstaller не нашёл. Если собранная программа падает сModuleNotFoundError, причину ищут там.itogi.spec— настройки сборки текстом (какой скрипт, какие флаги). Пригодится, когда настроек станет много: тогда собирают командойpython -m PyInstaller itogi.spec.
Exe из папки dist\itogi работает только вместе с соседней _internal. Мы скопировали один itogi.exe в пустую папку и запустили — программа не стартовала:
[PYI-47816:ERROR] Failed to load Python DLL '...\alone\_internal\python314.dll'.
Загрузчик ищет интерпретатор в _internal рядом с собой и не находит. Поэтому коллеге отправляют папку dist\itogi целиком: правый щелчок → «Отправить» → «Сжатая ZIP-папка», и уже архив — по почте или в мессенджер.

Проверьте себя
Задание. Дерево ниже — результат сборки утилиты поиска по журналу. Какой файл коллега должен запустить двойным щелчком? Введите имя файла с расширением.
poisk\
├── poisk.py
├── poisk.spec
├── build\
│ └── poisk\
│ ├── poisk.pkg
│ └── warn-poisk.txt
└── dist\
└── poisk\
├── poisk.exe
└── _internal\
├── python314.dll
└── base_library.zip
Подсказка: Готовая программа лежит в одной из двух папок сборки. Какая из них?
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Сборка сортировщика sorter.py прошла без флагов. Что отправить коллеге, чтобы у него программа запустилась?
Подсказка: Что случилось, когда exe скопировали в пустую папку одного? Чего ему не хватило?
Онлайн-проверка ответа появится позже
Задание. Собранная программа у вас падает с ModuleNotFoundError. В каком файле PyInstaller записал модули, которые не нашёл при сборке? Скрипт называется sorter.py. Введите имя файла с расширением.
Подсказка: Файл лежит в build\sorter\ и начинается со слова warn.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
—onefile: один файл вместо папки
Папка с 53 файлами неудобна: легко отправить не всё. Флаг --onefile (короткая запись -F) собирает один exe. По умолчанию действует обратный режим — --onedir (-D), «папка».
python -m PyInstaller --onefile proverka.py
dist\
└── proverka.exe (9 349 808 байт — примерно 9 МБ)
Внутри этого файла те же интерпретатор и библиотеки, только сжатые. Цена удобства:
- Запуск медленнее. При каждом старте загрузчик распаковывает содержимое во временную папку вида
_MEIxxxxxx(в Windows — внутри%TEMP%) и только потом запускает Python. Для утилиты на пару секунд это заметно. - Два процесса. В Диспетчере задач у запущенной onefile-программы два процесса с одним именем: загрузчик и сама программа. Мы проверили: у
okno.exeих было два. Это нормально. - Мусор после сбоя. Если программа аварийно закрылась, временная папка
_MEI…может остаться в%TEMP%.

Проверьте себя
Задание. Какой флаг добавить к команде python -m PyInstaller sorter.py, чтобы получить один exe-файл вместо папки? Введите флаг с дефисами. Короткая запись тоже подойдёт — с правильным регистром буквы.
Подсказка: Режим «папка» называется —onedir. Как тогда называется режим «один файл»?
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Программа собрана в один файл. Почему она стартует дольше, чем та же программа, собранная папкой?
Подсказка: Где лежат интерпретатор и библиотеки, пока программа не запущена, и где они должны оказаться, чтобы Python их прочитал?
Онлайн-проверка ответа появится позже
—windowed: программа с окном без чёрной консоли
Если собрать окно Tkinter из урока 3.2 без флагов и запустить двойным щелчком, рядом с окном откроется чёрная консоль. Для программы с окном она лишняя. Флаг --windowed (синонимы -w и --noconsole) собирает программу без консоли. На macOS тот же флаг собирает приложение .app:
import tkinter as tk
root = tk.Tk()
root.title("Итоги")
tk.Label(root, text="Привет из exe").pack()
root.mainloop()
python -m PyInstaller --onefile --windowed okno.py
Флаги сочетаются: здесь один файл dist\okno.exe (около 12 МБ — внутри ещё и Tkinter), и без консоли. В файле okno.spec это видно строкой console=False; у сборки без флага там console=True.
У программы с
--windowedнет консоли, значитprint()никто не увидит, аinput()работать не будет. Утилиту командной строки из урока 3.1 (argparse, вывод в терминал) собирают без--windowedи запускают из терминала:itogi.exe rashody.csv --month 2026-09.
Ещё два флага пригодятся для красоты: --name Итоги (-n) задаёт имя exe и .spec вместо имени скрипта, --icon app.ico — значок файла (родной формат для Windows — .ico; картинку другого формата, например .png, PyInstaller переведёт сам, если установлен пакет Pillow).
Проверьте себя
Задание. Вы собрали сортировщик с окном Tkinter, и при двойном щелчке за окном открывается чёрная консоль. Какой флаг добавить к сборке, чтобы её не было? Введите флаг с дефисами.
Подсказка: Флаг связан со словом «окно» по-английски; есть и синоним со словом console.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Какую программу курса собирать без чёрной консоли?
Подсказка: Что пропадает у программы вместе с консолью и кому из двух программ это не мешает?
Онлайн-проверка ответа появится позже
Контрольный вопрос. Сортировщик sorter.py с окном Tkinter нужно собрать в один файл без чёрной консоли, а exe должен называться Сортировщик.exe. Какая команда это сделает?
Подсказка: Проверьте каждую команду по трём требованиям: один файл, нет консоли, имя exe. Что задаёт имя exe — флаг или имя скрипта в конце команды?
Онлайн-проверка ответа появится позже
Файлы рядом с exe: где программе искать settings.json
Сортировщик из урока 3.3 хранит настройки в settings.json. Коллега распакует архив, положит settings.json рядом с exe — и программа должна его найти. Здесь две ловушки.
Ловушка 1: относительный путь. Path("settings.json") ищет файл не рядом с программой, а в рабочей папке — той, из которой программу запустили. При двойном щелчке это обычно папка exe, но при запуске из терминала, через ярлык или планировщик — любая другая.
Ловушка 2: __file__ в собранной программе. В обычном скрипте Path(__file__).parent — папка скрипта. В собранной программе загрузчик ставит __file__ внутрь сборки, и к exe он не ведёт ни в одном режиме: в onefile — во временную распаковку _MEI…, в onedir — в папку _internal рядом с exe.
PyInstaller даёт два признака. sys.frozen — атрибут, который загрузчик добавляет в модуль sys; в обычном Python его нет, поэтому читают через getattr(sys, "frozen", False): третий аргумент — значение, если атрибута нет. sys.executable — полный путь к запущенному файлу: в обычном Python это python.exe, в собранной программе — ваш exe (по документации — и в onedir, и в onefile). Проверим программой proverka.py, собранной с --onefile; рядом с exe в dist положили settings.json, а запустили из соседней папки elsewhere:
import sys
from pathlib import Path
print("sys.executable ->", Path(sys.executable).name, "в папке", Path(sys.executable).parent.name)
print("__file__ в папке", Path(__file__).parent.name)
print("рабочая папка", Path.cwd().name)
print("settings.json по относительному пути есть?", Path("settings.json").exists())
print("settings.json рядом с exe есть?", (Path(sys.executable).parent / "settings.json").exists())
> cd C:\Users\ученик\Desktop\itogi\elsewhere
> ..\dist\proverka.exe
sys.executable -> proverka.exe в папке dist
__file__ в папке _MEI0000d8142
рабочая папка elsewhere
settings.json по относительному пути есть? False
settings.json рядом с exe есть? True
Относительный путь промахнулся (рабочая папка — elsewhere), __file__ ведёт во временную _MEI… (у onedir-сборки он вёл бы в _internal), а sys.executable — ровно к exe. Отсюда рецепт, который уже стоял в itogi.py:
def app_dir():
if getattr(sys, "frozen", False):
return Path(sys.executable).parent
return Path(__file__).parent
В собранной программе — папка exe, при обычном запуске python itogi.py — папка скрипта. Проверка сборкой из раздела про установку: положили в dist\itogi файл settings.json с {"limit": 45000} и запустили itogi.exe:
Папка программы: C:\Users\ученик\Desktop\itogi\dist\itogi
frozen: True
Лимит: 45000
Тот же скрипт без сборки печатает frozen: False, папку скрипта и лимит по умолчанию 30000, потому что рядом со скриптом settings.json нет.
Для заданий пригодится PureWindowsPath из pathlib: он умеет всё то же, что Path, с путями (.parent, .name), но не обращается к диску и понимает пути Windows на любой ОС:
from pathlib import PureWindowsPath
p = PureWindowsPath(r"D:\Программы\sorter\sorter.exe")
print(p.parent)
print(p.name)
D:\Программы\sorter
sorter.exe
Файлы, которые пользователь должен менять (настройки, списки), держите рядом с exe и ищите через
app_dir(). В onefile-сборку их не зашивайте: всё, что внутри, распаковывается заново при каждом запуске, и изменения пропадут. Встроить в сборку неизменяемый файл (шаблон, картинку) можно флагом--add-data— это за рамками урока.

Проверьте себя
Задание. Программа sorter.exe и её settings.json лежат в папке D:\Программы\sorter. Её запустили из терминала, как показано ниже. Что вернёт в этой программе Path(«settings.json»).exists()? Введите True или False.
> cd C:\Users\ученик\Documents
> D:\Программы\sorter\sorter.exe
Подсказка: Относительно какой папки Python ищет файл по относительному пути — папки exe или рабочей папки? Какая рабочая папка у этого запуска?
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Сортировщик собран в режиме —onedir, готовая программа лежит в D:\Программы\sorter (там sorter.exe и папка _internal). Куда в собранной программе ведёт Path(__file__).parent?
Подсказка: Перечитайте «Ловушку 2»: куда загрузчик ставит __file__ в собранной программе и чем здесь onedir отличается от onefile?
Онлайн-проверка ответа появится позже
Задание. Ту же строку собрали PyInstaller в check.exe и запустили двойным щелчком. Что она выведет? Введите значение, как его напечатает Python.
Исходный код для этого задания:
import sys print(getattr(sys, "frozen", False))Подсказка: Кто добавляет атрибут frozen в модуль sys и в какой программе он есть?
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Задание. Соберите решение целиком. Напишите функцию app_dir(frozen, executable, file), которая работает как app_dir() из урока, но получает признаки аргументами: если frozen истинно — возвращает папку файла executable, иначе папку файла file. Пути — строки Windows, поэтому оборачивайте их в PureWindowsPath. Вызовите print(app_dir(True, r»C:\Users\ученик\Desktop\itogi\itogi.exe», r»C:\Users\ученик\AppData\Local\Temp\_MEI58212\itogi.py»)). Введите строку, которую напечатает программа.
Исходный код для этого задания:
from pathlib import PureWindowsPath def app_dir(frozen, executable, file): ... # ваш код print(app_dir(True, r"C:\Users\ученик\Desktop\itogi\itogi.exe", r"C:\Users\ученик\AppData\Local\Temp\_MEI58212\itogi.py"))Подсказка: Одна проверка if и два return; у PureWindowsPath берите .parent. Какая ветка выполнится при frozen=True?
✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.
Онлайн-проверка ответа появится позже
Перед отправкой: короткий чек-лист
- Пути к своим файлам — через
app_dir(), не относительные. - Собрать в виртуальном окружении:
--onedirдля отладки,--onefileдля отправки; окно Tkinter — с--windowed. - Запустить exe из другой папки и на компьютере без Python (или у коллеги) — только так видно, что файлы находятся.
- Если exe молча закрывается — собрать без
--windowedи запустить из терминала: текст ошибки будет виден. Не хватает модуля — смотретьbuild\…\warn-….txt. - Отправить папку
dist\…архивом (или один onefile-exe) вместе сsettings.jsonи исходником.py, предупредить про возможную реакцию антивируса.
Соберите свою утилиту из урока 3.3 дважды — папкой и одним файлом, положите рядом
settings.jsonи запустите оба варианта из другой папки через терминал. Сравните время запуска.
Задание. Проектная миссия «Что уезжает к коллеге». Перед отправкой вы хотите знать, сколько весит архив для коллеги. Ниже — список всех файлов папки проекта itogi после сборки —onedir (файл spisok.txt, utf-8, 72 строк «путь от папки проекта;размер в байтах»; файлы _internal — из реальной сборки урока). В dist лежат две сборки: текущая itogi и старая itogi-v1, которую отправлять не нужно. Напишите программу: читает файл построчно, разбирает строку через split(«;»), оставляет только файлы, которые по уроку отдают коллеге вместе с текущей сборкой, и печатает их суммарный размер в килобайтах: сумму байт разделить на 1024 и округлить round() до целого. Затем соберите свою утилиту из урока 3.3 в режиме —onedir. В поле ответа — число килобайт для данных из условия. Приложите файл программы .py и скриншот своей папки dist с exe; в поле ответа — число.
Принято, если:
1. введённое число совпадает с эталоном;
2. приложен файл .py, который это число выдаёт на данных из условия, и скриншот своей сборки в dist.Самопроверка перед сдачей (преподаватель смотрит на занятии):
3. в сумму не попали build, .spec, исходник и старая сборка — вы можете объяснить, почему каждый из них не уезжает;
4. на скриншоте видны exe и папка _internal рядом.itogi.py;612
itogi.spec;1012
settings.json;19
build\itogi\Analysis-00.toc;331904
build\itogi\base_library.zip;1388164
build\itogi\COLLECT-00.toc;43518
build\itogi\EXE-00.toc;3610
build\itogi\itogi.pkg;1573210
build\itogi\PKG-00.toc;3302
build\itogi\PYZ-00.pyz;1146892
build\itogi\PYZ-00.toc;28750
build\itogi\warn-itogi.txt;2215
build\itogi\xref-itogi.html;318440
dist\itogi\itogi.exe;2097893
dist\itogi\settings.json;19
dist\itogi\_internal\_bz2.pyd;87384
dist\itogi\_internal\_decimal.pyd;290648
dist\itogi\_internal\_hashlib.pyd;69464
dist\itogi\_internal\_lzma.pyd;161112
dist\itogi\_internal\_socket.pyd;87384
dist\itogi\_internal\_ssl.pyd;184664
dist\itogi\_internal\_zstd.pyd;503640
dist\itogi\_internal\api-ms-win-core-console-l1-1-0.dll;19864
dist\itogi\_internal\api-ms-win-core-datetime-l1-1-0.dll;19352
dist\itogi\_internal\api-ms-win-core-debug-l1-1-0.dll;19352
dist\itogi\_internal\api-ms-win-core-errorhandling-l1-1-0.dll;19376
dist\itogi\_internal\api-ms-win-core-file-l1-1-0.dll;22928
dist\itogi\_internal\api-ms-win-core-file-l1-2-0.dll;19344
dist\itogi\_internal\api-ms-win-core-file-l2-1-0.dll;19336
dist\itogi\_internal\api-ms-win-core-handle-l1-1-0.dll;19352
dist\itogi\_internal\api-ms-win-core-heap-l1-1-0.dll;19856
dist\itogi\_internal\api-ms-win-core-interlocked-l1-1-0.dll;19368
dist\itogi\_internal\api-ms-win-core-libraryloader-l1-1-0.dll;19888
dist\itogi\_internal\api-ms-win-core-localization-l1-2-0.dll;21936
dist\itogi\_internal\api-ms-win-core-memory-l1-1-0.dll;19856
dist\itogi\_internal\api-ms-win-core-namedpipe-l1-1-0.dll;19360
dist\itogi\_internal\api-ms-win-core-processenvironment-l1-1-0.dll;20424
dist\itogi\_internal\api-ms-win-core-processthreads-l1-1-0.dll;21432
dist\itogi\_internal\api-ms-win-core-processthreads-l1-1-1.dll;19896
dist\itogi\_internal\api-ms-win-core-profile-l1-1-0.dll;18840
dist\itogi\_internal\api-ms-win-core-rtlsupport-l1-1-0.dll;19880
dist\itogi\_internal\api-ms-win-core-string-l1-1-0.dll;19352
dist\itogi\_internal\api-ms-win-core-synch-l1-1-0.dll;21392
dist\itogi\_internal\api-ms-win-core-synch-l1-2-0.dll;19856
dist\itogi\_internal\api-ms-win-core-sysinfo-l1-1-0.dll;20376
dist\itogi\_internal\api-ms-win-core-timezone-l1-1-0.dll;19360
dist\itogi\_internal\api-ms-win-core-util-l1-1-0.dll;19336
dist\itogi\_internal\api-ms-win-crt-conio-l1-1-0.dll;20368
dist\itogi\_internal\api-ms-win-crt-convert-l1-1-0.dll;23448
dist\itogi\_internal\api-ms-win-crt-environment-l1-1-0.dll;19872
dist\itogi\_internal\api-ms-win-crt-filesystem-l1-1-0.dll;21408
dist\itogi\_internal\api-ms-win-crt-heap-l1-1-0.dll;20360
dist\itogi\_internal\api-ms-win-crt-locale-l1-1-0.dll;19856
dist\itogi\_internal\api-ms-win-crt-math-l1-1-0.dll;28552
dist\itogi\_internal\api-ms-win-crt-process-l1-1-0.dll;20376
dist\itogi\_internal\api-ms-win-crt-runtime-l1-1-0.dll;23960
dist\itogi\_internal\api-ms-win-crt-stdio-l1-1-0.dll;25480
dist\itogi\_internal\api-ms-win-crt-string-l1-1-0.dll;25496
dist\itogi\_internal\api-ms-win-crt-time-l1-1-0.dll;21896
dist\itogi\_internal\api-ms-win-crt-utility-l1-1-0.dll;19864
dist\itogi\_internal\base_library.zip;1388164
dist\itogi\_internal\libcrypto-3.dll;5229424
dist\itogi\_internal\libssl-3.dll;794992
dist\itogi\_internal\python314.dll;6753112
dist\itogi\_internal\select.pyd;33624
dist\itogi\_internal\ucrtbase.dll;1046056
dist\itogi\_internal\unicodedata.pyd;758104
dist\itogi\_internal\VCRUNTIME140.dll;120400
dist\itogi-v1\itogi-v1.exe;2091520
dist\itogi-v1\_internal\python314.dll;6753112
dist\itogi-v1\_internal\base_library.zip;1386012
dist\itogi-v1\_internal\VCRUNTIME140.dll;120400
Подсказка: Какая папка уезжает к коллеге целиком, а что остаётся у вас? Отбирайте строки по началу пути (startswith). Подумайте, почему образец начала пути должен заканчиваться слешем, — иначе в сумму попадёт и старая сборка. В строке Python обратный слеш пишут двойным.
✅ Готово, если: ответ раскрывает то, что просит критерий приёмки в задании выше.
Онлайн-проверка ответа появится позже
Задание. Проектная миссия «Где потерялись настройки». Коллеги жалуются: утилиты то видят свой settings.json, то работают со значениями по умолчанию. Вы собрали журнал 50 запусков (файл zapuski.txt, utf-8, данные целиком ниже): строка «полный путь к exe;рабочая папка при запуске». Файл settings.json лежит только в этих папках: C:\Users\ученик\Desktop\itogi, D:\Программы\sorter, C:\Users\ученик, E:\Флешка\poisk. Напишите программу, которая для каждого запуска решает две вещи: нашёл бы файл старый код с Path(«settings.json») (он ищет в рабочей папке) и нашёл бы новый код с app_dir() (он ищет в папке exe — берите str(PureWindowsPath(путь).parent)). Программа печатает, в скольких запусках старый код файл НЕ находит, а новый — находит. Затем замените у себя в утилите из урока 3.3 чтение настроек на app_dir(), соберите её с —onefile —windowed и запустите из другой папки. В поле ответа — число для данных из условия. Приложите файл программы .py и файл .spec своей сборки; в поле ответа — число.
Принято, если:
1. введённое число совпадает с эталоном;
2. приложен файл .py, который это число выдаёт на данных из условия, и .spec своей сборки со строкой console=False.Самопроверка перед сдачей (преподаватель смотрит на занятии):
3. папки с settings.json хранятся в множестве, а проверка — через in;
4. ваша собранная утилита находит settings.json рядом с exe при запуске из другой папки.C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Users\ученик\Documents\Утилиты\itogi
E:\Флешка\poisk\poisk.exe;C:\Users\ученик\Desktop
C:\Users\ученик\Desktop\itogi\itogi.exe;C:\Users\ученик\Desktop\itogi
D:\Программы\sorter\sorter.exe;D:\Программы\sorter
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Windows\System32
C:\Users\ученик\Desktop\itogi\itogi.exe;C:\Users\ученик\Desktop\itogi
C:\Users\ученик\Desktop\itogi\itogi.exe;C:\Users\ученик\Desktop\itogi
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Users\ученик\Documents\Утилиты\itogi
C:\Users\ученик\Desktop\poisk.exe;C:\Users\ученик\Documents\Утилиты\itogi
E:\Флешка\poisk\poisk.exe;C:\Users\ученик\Desktop\itogi
E:\Флешка\poisk\poisk.exe;C:\Users\ученик\Desktop
D:\Программы\sorter\sorter.exe;D:\Программы\sorter
D:\Программы\sorter\sorter.exe;E:\Флешка\poisk
C:\Users\ученик\Desktop\poisk.exe;C:\Users\ученик\Desktop
C:\Users\ученик\Desktop\itogi\itogi.exe;D:\Программы
D:\Программы\sorter\sorter.exe;D:\Программы\sorter
C:\Users\ученик\Desktop\poisk.exe;C:\Users\ученик\Desktop
C:\Users\ученик\Desktop\itogi\itogi.exe;C:\Users\ученик\Desktop\itogi
D:\Программы\sorter\sorter.exe;C:\Windows\System32
C:\Users\ученик\Desktop\poisk.exe;D:\Программы
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Users\ученик\Documents\Утилиты\itogi
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Users\ученик\Documents\Утилиты\itogi
C:\Users\ученик\Desktop\itogi\itogi.exe;C:\Windows\System32
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Windows\System32
C:\Users\ученик\Desktop\itogi\itogi.exe;C:\Users\ученик\Desktop\itogi
C:\Users\ученик\Desktop\poisk.exe;C:\Windows\System32
C:\Users\ученик\Desktop\itogi\itogi.exe;D:\Программы\sorter
C:\Users\ученик\Desktop\itogi\itogi.exe;C:\Users\ученик\Desktop
C:\Users\ученик\Desktop\poisk.exe;C:\Users\ученик\Desktop\itogi
E:\Флешка\poisk\poisk.exe;C:\Users\ученик\Downloads
C:\Users\ученик\Desktop\itogi\itogi.exe;D:\Программы
C:\Users\ученик\Desktop\itogi\itogi.exe;D:\Программы\sorter
E:\Флешка\poisk\poisk.exe;E:\Флешка\poisk
E:\Флешка\poisk\poisk.exe;C:\Windows\System32
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Users\ученик\Documents\Утилиты\itogi
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Users\ученик\Desktop\itogi
D:\Программы\sorter\sorter.exe;D:\Программы\sorter
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Users\ученик\Desktop\itogi
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Users\ученик\Documents\Утилиты\itogi
C:\Users\ученик\Desktop\itogi\itogi.exe;C:\Users\ученик\Desktop\itogi
E:\Флешка\poisk\poisk.exe;C:\Windows\System32
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Users\ученик\Documents\Утилиты\itogi
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;D:\Программы\sorter
E:\Флешка\poisk\poisk.exe;C:\Users\ученик\Downloads
C:\Users\ученик\Desktop\itogi\itogi.exe;C:\Users\ученик\Desktop\itogi
C:\Users\ученик\Documents\Утилиты\itogi\itogi.exe;C:\Users\ученик\Documents\Утилиты\itogi
C:\Users\ученик\Desktop\poisk.exe;E:\Флешка\poisk
C:\Users\ученик\Desktop\poisk.exe;D:\Программы\sorter
E:\Флешка\poisk\poisk.exe;C:\Windows\System32
D:\Программы\sorter\sorter.exe;C:\Users\ученик\Desktop
Подсказка: Для строки нужны три ответа: в какой папке ищет старый код, в какой — новый, и есть ли каждая из этих папок в множестве. Засчитывается только сочетание «старый — нет, новый — да».
✅ Готово, если: ответ раскрывает то, что просит критерий приёмки в задании выше.
Онлайн-проверка ответа появится позже
Что дальше
Теперь вы умеете собирать утилиту в exe папкой и одним файлом, убирать консоль у программы с окном, находить результат в dist и отдавать его целиком, а настройки искать рядом с exe через sys.frozen и sys.executable. Глава 3 пройдена: ваши утилиты принимают параметры, показывают окно и запускаются у людей без Python. Дальше — итоговая работа курса: своя утилита от задумки до собранного exe.
← Назад · ↑ В начало урока · ⌂ К навигатору курса · Вперёд →
