Я написал препроцессор python под названием pypreprocessor, который делает именно то, что вы описываете.
Источник и документация доступны на GitHub .
Пакет также можно загрузить / установить через PyPI .
Вот пример, чтобы выполнить то, что вы описываете.
from pypreprocessor import pypreprocessor
pypreprocessor.parse()
#define debug
#ifdef debug
print('The source is in debug mode')
#else
print('The source is not in debug mode')
#endif
pypreprocessor способен намного больше, чем просто предварительная обработка на лету. Чтобы увидеть больше примеров использования, ознакомьтесь с проектом в Google Code.
Обновление: больше информации о pypreprocessor
Способ, которым я выполняю предварительную обработку, прост. Из приведенного выше примера препроцессор импортирует объект pypreprocessor, созданный в модуле pypreprocessor. Когда вы вызываете parse () для препроцессора, он самостоятельно потребляет файл, в который он импортирован, и генерирует временную копию себя, которая закомментирует весь код препроцессора (чтобы избежать препроцессора от рекурсивного вызова себя в бесконечном цикле) и комментирует все неиспользованные части.
Комментирование строк, в отличие от их удаления, необходимо для сохранения номеров строк в трассировках ошибок, если модуль выдает исключение или вылетает. И я даже зашел так далеко, что переписал трассировку ошибок, чтобы отчет отражал правильное имя файла модуля, который упал.
Затем сгенерированный файл, содержащий постобработанный код, выполняется на лету.
Преимущество использования этого метода по сравнению с простым добавлением в код встроенных операторов if не приведет к потере времени выполнения при оценке бесполезных операторов, поскольку закомментированные части кода будут исключены из скомпилированных файлов .pyc. .
Недостатком (и моей первоначальной причиной создания модуля) является то, что вы не можете запустить и python 2x, и python 3x в одном файле, потому что интерпретатор pythons выполняет полную проверку синтаксиса перед выполнением кода и отклоняет любую конкретную версию код до того, как препроцессору будет разрешено запускать :: sigh ::. Моя первоначальная цель состояла в том, чтобы иметь возможность разрабатывать 2х и 3х кодовый код в одном и том же файле, который создавал бы специфичный для версии байт-код в зависимости от того, на чем он выполняется.
В любом случае, модуль препроцессора все еще очень полезен для реализации общих возможностей предварительной обработки в стиле c. Кроме того, препроцессор способен выводить постобработанный код в файл для последующего использования, если хотите.
Кроме того, если вы хотите сгенерировать версию, в которой удалены все директивы препроцессора, а также исключены все #ifdef, которые исключены, это так же просто, как установить флаг в коде препроцессора перед вызовом parse (). Это делает удаление нежелательного кода из исходного файла конкретной версии одношаговым процессом (против обхода кода и удаления операторов if вручную).