Как Вы сделали бы эквивалент директив препроцессору в Python?

Вот мое решение (hacky?), чтобы обойти проблему уродливого текстового узла.

uglyXml = doc.toprettyxml(indent='  ')

text_re = re.compile('>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL)    
prettyXml = text_re.sub('>\g<1></', uglyXml)

print prettyXml

Вышеприведенный код будет генерировать:

<?xml version="1.0" ?>
<issues>
  <issue>
    <id>1</id>
    <title>Add Visual Studio 2005 and 2008 solution files</title>
    <details>We need Visual Studio 2005/2008 project files for Windows.</details>
  </issue>
</issues>

Вместо этого:

<?xml version="1.0" ?>
<issues>
  <issue>
    <id>
      1
    </id>
    <title>
      Add Visual Studio 2005 and 2008 solution files
    </title>
    <details>
      We need Visual Studio 2005/2008 project files for Windows.
    </details>
  </issue>
</issues>

Отказ от ответственности: Вероятно, существуют некоторые ограничения.

60
задан intrepion 27 January 2009 в 01:10
поделиться

5 ответов

Существует __debug__, который является специальным значением, которое действительно предварительно обрабатывает компилятор.

if __debug__:
  print "If this prints, you're not running python -O."
else:
  print "If this prints, you are running python -O!"

__debug__ будет заменен постоянным 0 или 1 компилятором, и оптимизатор удалит любой if 0: строки, прежде чем Ваш источник будет интерпретирован.

103
ответ дан habnabit 7 November 2019 в 13:58
поделиться

Я подозреваю, что Вы собираетесь ненавидеть этот ответ. Путем Вы делаете это в Python

# code here
if DEBUG:
   #debugging code goes here
else:
   # other code here.

, Так как Python является интерпретатором, нет никакого шага предварительной обработки, который будет применен, и никакое конкретное преимущество для наличия специального синтаксиса.

22
ответ дан Charlie Martin 7 November 2019 в 13:58
поделиться

Можно просто использовать нормальные конструкции языка:

DEBUG = True
if DEBUG:
  # Define a function, a class or do some crazy stuff
  def f():
    return 23
else:
  def f():
    return 42
4
ответ дан phihag 7 November 2019 в 13:58
поделиться

Можно использовать препроцессор в Python. Просто запустите свои скрипты через cpp (C-препроцессор) в Вашем каталоге bin. Однако я сделал это с Lua, и преимущества легкой интерпретации перевесили более сложную компиляцию, по моему скромному мнению.

10
ответ дан Robert Gould 7 November 2019 в 13:58
поделиться

Я написал препроцессор для 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::. Моя первоначальная цель состояла в том, чтобы иметь возможность разрабатывать 2x и 3x код бок о бок в одном файле, который бы создавал байткод, специфичный для конкретной версии, в зависимости от того, на чем он выполняется.

В любом случае, модуль препроцессора по-прежнему очень полезен для реализации общих возможностей препроцессирования в стиле c. Кроме того, препроцессор способен выводить постпроцессированный код в файл для последующего использования, если вы хотите.

Кроме того, если вы хотите сгенерировать версию, которая содержит все директивы препроцессора, а также все исключенные #ifdef, то это просто: установите флаг в коде препроцессора перед вызовом parse(). Это делает удаление ненужного кода из исходного файла конкретной версии одношаговым процессом (по сравнению с ползанием по коду и удалением операторов if вручную).

34
ответ дан 24 November 2019 в 17:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: