К содержанию
fohbookбета/ TouchDesigner

Ошибки Python и модулей

Python сломался. Где искать ошибку без отладчика, почему маркер висит не на том DAT, что проверить при ModuleNotFoundError и какими командами TouchDesigner помогает разбираться.

Ветка вашего пульта:
Быстрый выбор:

Пошагового отладчика нет: это система реального времени, поэтому начинают с Textport (Alt+T). Удобнее держать его панелью рядом с сетью, тип Textport and DATs.

На DAT, который не компилируется, появляется красный значок, текст — по щелчку или среднему клику. Ошибка при выполнении ставит маркер на DAT, откуда выполнение началось, хотя случилась она, может, в другом модуле; вся цепочка вызовов — в маркере и Textport. Все ошибки проекта — Dialogs → Errors с переходом к узлу или Error DAT таблицей и с колбэками, а из Textport — op('/').errors(recurse=True) и op('/').scriptErrors(recurse=True).

Импорт

ModuleNotFoundError. Пакет с двоичными частями собран под ту же версию Python, что внутри TouchDesigner: 3.11 в ветке 2025.30000, 3.14 в экспериментальной 2026.20000. В Edit → Preferences → General включён Add External Python to Search Path, путь в Python 64-bit Module Path, несколько — через ;. Новые пути заработают после перезапуска. Проверка изнутри:

import sys
for p in sys.path: print(p)

Окружения и TDPyEnvManager — Внешние модули и окружения.

Импорт прошёл, а потом всё падает — подменили встроенные numpy или OpenCV. Чужая их версия роняет TouchDesigner молча, иногда через час. Конфликтующее не подключают; если библиотека нужна, её выносят в отдельный процесс.

Молчит

Симптом Причина
Ничего и без ошибок Колбэк не включён параметром или DAT выключен (Active)
Работал и перестал Внутри было исключение — Textport и маркер
Сработал раз Так и задумано, это не цикл
В редакторе да, в Perform нет Узел считался благодаря вьюеру
Значение не обновляется Выражение не зависит от меняющегося — Ссылки, выражения и экспорт

На шоу колбэки оборачивают в try/except с записью в лог: колбэк, который молча перестал работать, хуже громкой ошибки.

AttributeError: 'NoneType' object has no attribute ... — op('имя') ничего не нашёл; относительный путь считается от оператора, где идёт код. Код, который создаёт, удаляет или переподключает операторы прямо из кука другого оператора (скажем, из колбэка Script-оператора), может упасть с ошибкой — такое откладывают на кадр:

run("op('base1').create(nullTOP)", delayFrames=1)

Интерфейс застыл — главный поток занят сетевым запросом, большим файлом или моделью. В поток или в отдельный процесс — Отложенный запуск и потоки.

Инструменты

debug('ширина', w)              # как print, но с именем DAT и строкой
print(project.pythonStack())    # кто нас вызвал
op('null1').errors()            # ошибки узла
op('null1').warnings()          # предупреждения
raise Exception('width = 0 в ' + parent().path)   # стоп с понятным текстом

debug() всегда пишет, откуда вызван, и забытые отладочные строки находятся сами. Если отладочных данных много, их пишут в Table DAT — они сохранятся вместе с проектом. Время кусков скрипта — time.perf_counter(). Error DAT на служебной панели показывает на площадке, что выдаёт ошибки, Мониторинг.

Рабочая комбинация версий

Сборка, Python, пакеты, драйвер — записать. Через полгода при переустановке это сбережёт день.

Нашли в статье ошибку, устаревшее или непонятное место?

рядом по смыслу