Какова эквивалентная особенность флагов компилятора C++ в Python?
Я хочу сохранить одну кодовую базу, где я могу динамически включать и отключать некоторый набор функций для другой версии сборки. Конечно, я могу сделать это с флагами компилятора в C/C++, имея несколько конфигураций сборки. Но как я могу сделать это с Python? Есть ли в Python эквивалентная технология?
1 ответ
В C, конечно, препроцессор используется для определения того, какие части программы включены или исключены. Существует четкое и быстрое разграничение между препроцессором и основным кодом программы.
Нет препроцессора и, следовательно, нет такого разграничения в Python, что может показаться странным для программиста на Си. Но то, что такого разграничения нет, не означает, что вы не можете перенастроить свое приложение.
Python чрезвычайно динамичен - одна из приятных особенностей Python заключается в том, что приложение можно даже перенастроить "на лету", читая файлы конфигурации в специальном формате (некоторые из них поддерживаются в стандартной библиотеке) или даже в Python.
Существуют расширенные способы перенастройки приложения, но простейшим, вероятно, является наличие файла конфигурации, который является чистым Python. Например, вы могли бы иметь myconfig.py
это имеет такие утверждения, как:
use_widgets = True
use_cogs = False
Этот скрипт конфигурации Python может даже существовать там, где пользователь выполняет программу; это поведение легко поддерживается добавлением текущего каталога в путь поиска модуля:
import sys
sys.path.insert(0, '.')
import myconfig
Как вы знаете, в Си, #if
более эффективен, чем if
потому что результаты предварительно рассчитаны перед выполнением. Python не имеет #if
, но в отличие от C, if
операторы могут легко существовать вне любой функции, поэтому вы можете заменить целые разделы кода в зависимости от вашей конфигурации:
if myconfig.use_widgets:
def myfunc(.....):
<definition that uses widgets>
else:
def myfunc(.....):
<non-widget definition>
Когда модуль импортируется, Python скомпилирует все это (если он еще не был предварительно скомпилирован в файл.pyc), а затем выполнит тело модуля. Это выполнение будет связывать первое определение модуля (для использования виджета myfunc
) к идентификатору myfunc
в глобальных переменных модуля, и сразу же отбросить не-виджет myfunc
(не выполняя else
пункт).
Это немного менее эффективно при запуске, чем один myfunc
, но после запуска нет штрафных санкций во время выполнения - второй myfunc исчезает и больше никогда не видится, а первый myfunc, оптимизированный для случая, когда у вас есть виджеты, - это тот, который выполняется всякий раз, когда другая часть программы звонки myfunc
,