Подтвердить что ты не робот

Каков питонический способ инициализации условной переменной?

Из-за правил определения области видимости 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 готовым к использованию за пределами этого раздела функции.

Я видел, как последняя конструкция использовалась несколько раз в других вопросах, таких как:

Какая конструкция будет более приемлемой?

4b9b3361

Ответ 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 позже может получить исключение неинициализированной переменной.