Отдать программу: exe через PyInstaller, —onefile и —windowed, файлы рядом с exe

Вспомните: в уроках 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 не установлен.

Три честные оговорки, которые стоит знать до первой сборки:

  1. Сборка — под свою систему. В документации прямо сказано: PyInstaller не кросс-компилятор. Exe для Windows собирают на Windows, программу для macOS — на Mac, для Linux — на Linux. Результат привязан и к ОС, и к версии Python, на которой собирали.
  2. Антивирус может ругаться. Незнакомый exe без цифровой подписи, который при запуске распаковывает файлы во временную папку, — ровно то, что антивирусы проверяют с подозрением. Бывает, что Защитник Windows или другой антивирус блокирует свежесобранную программу или помещает её в карантин. Это не значит, что в ней вирус; скажите коллеге заранее и отправляйте исходник .py рядом, чтобы было видно, что внутри.
  3. Размер. Даже скрипт в 20 строк тянет за собой интерпретатор: папка сборки ниже весит около 20 МБ, один файл с окном Tkinter — около 12 МБ.
Схема упаковки. Слева три прямоугольника: «itogi.py — ваш скрипт», «модули, которые он импортирует: json, pathlib, sys», «интерпретатор python314.dll». Стрелки от всех трёх ведут в воронку с подписью «PyInstaller». Из воронки справа выходит папка «dist\itogi\» с файлом «itogi.exe (загрузчик)» и папкой «_internal (Python и библиотеки)». Внизу серая плашка: «собрано на Windows → работает на Windows».

Проверьте себя

Контрольный вопрос. Что делает PyInstaller со скриптом itogi.py?

АПереводит код Python в машинный код процессора
БСкладывает скрипт, нужные модули и копию интерпретатора Python в папку с запускающим exe
ВУстанавливает Python на компьютер коллеги при первом запуске
ГЗагружает скрипт в интернет и выдаёт ссылку на запуск

Подсказка: Вспомните, какой файл из _internal отвечает за сам язык Python и зачем он лежит рядом с exe.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Вы работаете на Windows. Коллеге с MacBook нужна ваша утилита. Как получить версию для macOS?

АСобрать на Windows с флагом —onefile — один файл запустится везде
БСобрать на Windows и переименовать itogi.exe в itogi.app
ВЗапустить PyInstaller на компьютере с macOS
ГНикак: PyInstaller собирает только под Windows

Подсказка: Перечитайте первую оговорку: к чему привязан результат сборки?

Онлайн-проверка ответа появится позже

Установка и первая сборка

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-папка», и уже архив — по почте или в мессенджер.

Окно Проводника Windows с папкой dist\itogi. Слева дерево: itogi → build, dist → itogi → _internal. Справа содержимое dist\itogi: папка _internal и файл itogi.exe, выделенный синим. Зелёная рамка обводит обе строки с подписью «отдавать всё это, архивом». Папка build в дереве серая с подписью «не отдавать».

Проверьте себя

Задание. Дерево ниже — результат сборки утилиты поиска по журналу. Какой файл коллега должен запустить двойным щелчком? Введите имя файла с расширением.

poisk\

├── poisk.py

├── poisk.spec

├── build\

│ └── poisk\

│ ├── poisk.pkg

│ └── warn-poisk.txt

└── dist\

└── poisk\

├── poisk.exe

└── _internal\

├── python314.dll

└── base_library.zip

Подсказка: Готовая программа лежит в одной из двух папок сборки. Какая из них?

✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Сборка сортировщика sorter.py прошла без флагов. Что отправить коллеге, чтобы у него программа запустилась?

АТолько файл dist\sorter\sorter.exe
БПапку dist\sorter целиком, например ZIP-архивом
ВПапку build\sorter
ГФайл sorter.spec — по нему программа соберётся у коллеги

Подсказка: Что случилось, когда 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%.
Сравнение двух режимов в две колонки. Слева «--onedir (по умолчанию)»: папка dist\itogi с itogi.exe и _internal, плюсы «быстрый запуск», «видно, что внутри», минус «легко отправить не всё». Справа «--onefile»: один файл dist\proverka.exe, при запуске стрелка «распаковка» во временную папку _MEI…, плюс «один файл — нечего потерять», минусы «запуск медленнее», «антивирусы проверяют строже».

Проверьте себя

Задание. Какой флаг добавить к команде python -m PyInstaller sorter.py, чтобы получить один exe-файл вместо папки? Введите флаг с дефисами. Короткая запись тоже подойдёт — с правильным регистром буквы.

Подсказка: Режим «папка» называется —onedir. Как тогда называется режим «один файл»?

✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Программа собрана в один файл. Почему она стартует дольше, чем та же программа, собранная папкой?

АPython в onefile-сборке работает медленнее всегда, не только при старте
БПри каждом запуске загрузчик распаковывает Python и библиотеки во временную папку _MEI…
ВАнтивирус заново скачивает программу из интернета
ГExe в режиме onefile сначала устанавливает Python в систему

Подсказка: Где лежат интерпретатор и библиотеки, пока программа не запущена, и где они должны оказаться, чтобы 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.

✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Какую программу курса собирать без чёрной консоли?

АУтилиту итогов с argparse из урока 3.1, которая печатает итог в терминал
БСортировщик «Загрузок» с окном Tkinter из урока 3.3
ВЛюбую — флаг только ускоряет запуск
ГНикакую — флаг нужен лишь для macOS

Подсказка: Что пропадает у программы вместе с консолью и кому из двух программ это не мешает?

Онлайн-проверка ответа появится позже

Контрольный вопрос. Сортировщик sorter.py с окном Tkinter нужно собрать в один файл без чёрной консоли, а exe должен называться Сортировщик.exe. Какая команда это сделает?

Аpython -m PyInstaller —onedir —windowed —name Сортировщик sorter.py
Бpython -m PyInstaller —onefile —name Сортировщик sorter.py
Вpython -m PyInstaller —onefile —windowed —name Сортировщик sorter.py
Гpython -m PyInstaller —onefile —windowed Сортировщик.py

Подсказка: Проверьте каждую команду по трём требованиям: один файл, нет консоли, имя 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 — это за рамками урока.

Схема трёх путей для onefile-программы, запущенной из папки elsewhere. Три стрелки от надписи «proverka.exe запущен». Красная «Path("settings.json")» ведёт в папку elsewhere, где файла нет, — крестик. Серая «Path(__file__).parent» ведёт во временную папку %TEMP%\_MEI…, — крестик. Зелёная «Path(sys.executable).parent» ведёт в папку dist, где лежат proverka.exe и settings.json, — галочка.

Проверьте себя

Задание. Программа 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?

АD:\Программы\sorter\_internal
БD:\Программы\sorter
Вв рабочую папку, из которой запустили программу
Гво временную папку %TEMP%\_MEI…

Подсказка: Перечитайте «Ловушку 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?

✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.

Онлайн-проверка ответа появится позже

Перед отправкой: короткий чек-лист

  1. Пути к своим файлам — через app_dir(), не относительные.
  2. Собрать в виртуальном окружении: --onedir для отладки, --onefile для отправки; окно Tkinter — с --windowed.
  3. Запустить exe из другой папки и на компьютере без Python (или у коллеги) — только так видно, что файлы находятся.
  4. Если exe молча закрывается — собрать без --windowed и запустить из терминала: текст ошибки будет виден. Не хватает модуля — смотреть build\…\warn-….txt.
  5. Отправить папку 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.

← Назад · ↑ В начало урока · ⌂ К навигатору курса · Вперёд →

Школа Виктора Комлева