Каков питонический способ инициализации условной переменной?
Из-за правил определения области видимости Python все переменные, однажды инициализированные в пределах области действия, доступны после этого. Поскольку условные обозначения не вводят новую область, конструкции в других языках (например, инициализация переменной до этого условия) необязательно необходимы. Например, мы могли бы:
def foo(optionalvar = None):
# some processing, resulting in...
message = get_message()
if optionalvar is not None:
# some other processing, resulting in...
message = get_other_message()
# ... rest of function that uses message
или, мы могли бы вместо этого:
def foo(optionalvar = None):
if optionalvar is None:
# processing, resulting in...
message = get_message()
else:
# other processing, resulting in...
message = get_other_message()
# ... rest of function that uses message
Конечно, функции get_message
и get_other_message
могут быть много строк кода и в основном неактуальны (вы можете предположить, что состояние программы после каждого пути одинаково); цель здесь заключается в том, чтобы сделать message
готовым к использованию за пределами этого раздела функции.
Я видел, как последняя конструкция использовалась несколько раз в других вопросах, таких как:
Какая конструкция будет более приемлемой?
Ответы
Ответ 1
Python также имеет очень полезный шаблон синтаксиса, который вы можете использовать здесь
message = get_other_message() if optional_var else get_message()
Или, если вы хотите строго сравнить с None
message = get_other_message() if optional_var is not None else get_message()
В отличие от примера 1), вы опубликовали это, не вызвав get_message() без необходимости.
Ответ 2
В целом второй подход лучше и более общий, поскольку он не предполагает безоговорочного вызова get_message
. Что может быть хорошо, если эта функция не стимулирует ресурсы, но рассмотрит функцию поиска
def search(engine):
results = get_from_google()
if engine == 'bing':
results = get_from_bing()
очевидно, это нехорошо, я не могу придумать такой плохой сценарий для второго случая, поэтому в основном подход, который проходит через все параметры и, наконец, лучше всего подходит по умолчанию.
def search(engine):
if engine == 'bing':
results = get_from_bing()
else:
results = get_from_google()
Ответ 3
Я думаю, что более pythonic, чтобы не устанавливать явное правило об этом, а вместо этого просто придерживайтесь идеи о том, что маленькие функции лучше (отчасти потому, что можно держать в уме только при введении новых имен).
Я полагаю, что если ваши условные тесты будут намного сложнее, чем if/else
, вы можете запустить риск того, что все они потерпят неудачу, а позже вы используете имя undefined, что приведет к возможной ошибке во время выполнения, если вы не используете очень осторожно. Это может быть аргументом для первого стиля, когда это возможно.
Ответ 4
Ответ зависит от наличия побочных эффектов get_message()
.
В большинстве случаев ясно, что второй выигрывает, потому что код, который создает нежелательный результат, не выполняется. Но если вам нужны побочные эффекты, вы должны выбрать первую версию.
Ответ 5
Возможно, лучше (читай: безопаснее) инициализировать переменную вне условий. Если вам нужно определить другие условия или даже удалить некоторые, пользователь message
позже может получить исключение неинициализированной переменной.