Мне не нравится повторение - я думаю, что «СУХОЙ», «Не повторяй себя», является ключевым принципом программирования. Как следствие, я действительно использовал locals()
в подобных ситуациях. Визуализация шаблона Django - далеко не единственная ситуация такого рода: общий случай - это «функция или оператор, который принимает dict, но не возражает, если в dict есть дополнительные записи». (Например, обычное форматирование строк в Python является еще одним таким случаем).
Тем не менее, существует противоположный принцип: программы должны быть понятны настолько локализованно, насколько это возможно - это помогает в обслуживании и рефакторинге (поскольку это устраняет необходимость изучения других файлов, чтобы проверить, какие рефакторинги приемлемы). Для случая locals()
это говорит о том, что все в порядке, если шаблон (или формат строки и т. Д.) Является локальным литералом (редкий случай, когда, вероятно, используется только несколько переменных, и, таким образом, locals()
не является огромным выигрышем! -), но проблематично в обычном случае, когда шаблон находится в другом файле.
Таким образом, использование locals()
в большинстве случаев серьезно затрудняет рефакторинг. Почти в каждой ситуации в Python локальные переменные и их имена могут быть свободно изменены как часть локального рефакторинга, так как они не имеют "видимого извне" эффекта ... но использование locals()
прерывает это - внезапно вы не можете безопасно переименуйте переменную в другое имя, предлагая лучшую ясность, рефакторинг потока кода таким образом, что устраняет необходимость в переменной, и т. д., и т. д., при этом каждый раз не изучая отдельный файл шаблона, чтобы проверить, не нужно ли старое имя ( и, возможно, редактирование файла шаблона, который может быть нетривиальным, например, если он поддерживается на нескольких разных естественных языках для целей i18n / L10n).
Как следствие, в дополнение к вторичной проблеме производительности, существует сильное давление против с использованием locals()
в «серьезном», «производственном» коде - коде, который действительно требует длительного обслуживания и Поэтому легко рефакторинг и местность. Поэтому, когда я «программирую так хорошо, как умею», а не «срезаю углы», я осознаю, что мне лучше избегать locals()
.
Значения, которые вы хотите иметь в контексте, в котором отображается шаблон, не обязательно «естественно» доступны как локальные голые имена, в конце концов; может быть, некоторые или многие из них являются результатами вычислений, элементами из списков или словарей и т.п. В этом случае соблазна «срезать углы» с помощью locals()
легче избежать, если вы просто накапливаете эти значения в подходящий словарь, а не присваиваете им локальные голые имена.
Это не самый простой компромисс, потому что два хороших принципа (избегание повторения и хорошее месторасположение) неизбежно сталкиваются - следовательно, хороший вопрос! И не один полностью восприимчивый к острым черным или белым ответам, поэтому я попытался расширить с обеих сторон. В конце концов, я думаю, что это один из тех «стилевых» аспектов, когда команде программистов следует посоветовать принять единообразное руководство по стилю и придерживаться его - по крайней мере, это устраняет необходимость принимать решения снова и снова Со временем возникает проблема, и создается более однородная (и, следовательно, поддерживаемая) база кода. [[Я должен признаться, что этот конкретный момент никогда не рассматривался в руководстве по стилю команд, в которых я был, хотя многие другие это делали! -)]]