Python: "импорт *" против execfile

В некоторых из моих приложений Django я использую settings_local.py файл для переопределения настроек, которые различны в разных средах (например, разработка, тестирование и производство). Первоначально я использовал следующий код, чтобы включить его содержимое в settings.py:

try:
    from settings_local import *
except ImportError:
    sys.stderr.write("The settings_local.py file is missing.\n")
    DEBUG=False

Я недавно нашел execfile работать и переключаться на что-то вроде:

try:
    execfile(path.join(PROJECT_ROOT, "settings_local.py"))
except IOError:
    sys.stderr.write("The settings_local.py file is missing.\n"
    DEBUG=False

Оба работают как задумано, но мне любопытно, пропускаю ли я какие-либо ошибки, и вообще, какой подход более рекомендуется и почему.

3 ответа

Решение

С помощью execfile Функция будет приводить к оценке исходного файла Python (.py) при каждой оценке файла настроек. Вы выполняете парсер Python каждый раз. С помощью import не обязательно делать это (может использовать файл.pyc). Обычно при первом запуске проекта в Python (по крайней мере, cPython) он компилируется в байт-код и не перекомпилируется снова. Вы нарушаете это. Это не обязательно проблема, но вы должны знать об этом.

С помощью execfile также приведет ко всему импорту, который вы можете иметь в settings_local.py файл переоценивается в объеме модуля settings.py файл. С помощью import * включил бы все элементы в settings_local.py область применения модуля Чистый эффект одинаков (все элементы включены в settings_local.py Объем модуля включен в settings.py) но метод другой.

Наконец, вполне нормально, чтобы модули выполнялись как модули, а не включались. Разумно для кода включать такие вещи, как os.path.dirname(__file__), Если бы какой-либо код использовал это, вы бы запутали его, так как код больше не выполнялся бы в модуле, который автор мог разумно ожидать.

По моему опыту, люди используют import не execfile, Django - это "соглашение по конфигурации". Следуйте соглашению.

Еще одно отличие: execfile получает контекстный словарь; глобальный контекст по умолчанию или указанный словарь. Это может позволить некоторые странные вещи

dont_do_this.py:

# Probably not a good thing to do
z=x+1  # an expression that involves an un-defined field

Очевидно, что

from dont_do_this import *

выходит из строя.

Тем не мение,

d={'x':1}
execfile( 'dont_do_this.py', d )

в порядке и приводит к d=={'x':1, 'z':2}

Обратите внимание, что

x=1
execfile( 'dont_do_this.py' )

в порядке и приводит к переменной z добавляются в глобалы.

Первая версия (from settings_local import *) это то, что все ожидают увидеть. Это также позволит анализаторам кода найти модуль.

Другие вопросы по тегам