Python: избегать, если условие? - PullRequest
4 голосов
/ 11 марта 2010

Что лучше?

<code>if not var:
    var = get_var()
(Или)

var = var или get_var ()

Кроме того, как мне узнать лучшее из двух?
edit:
Еще одна опция от Стива,

var = var if var else get_var()

Ответы [ 9 ]

7 голосов
/ 11 марта 2010

Когда два стилевых варианта очень близки по стилистике, я использую timeit в качестве тай-брейка: чем быстрее, тем ближе к основной части Python, т.е. Эй, это лучше, чем бесконечные дебаты, у? -) Итак:

$ python -mtimeit -s'var=0; getvar=lambda:0' 'var = var or getvar()'
1000000 loops, best of 3: 0.359 usec per loop
$ python -mtimeit -s'var=0; getvar=lambda:0' 'if not var: var = getvar()'
1000000 loops, best of 3: 0.361 usec per loop
$ python -mtimeit -s'var=1; getvar=lambda:1' 'var = var or getvar()'
10000000 loops, best of 3: 0.123 usec per loop
$ python -mtimeit -s'var=1; getvar=lambda:1' 'if not var: var = getvar()'
10000000 loops, best of 3: 0.0899 usec per loop

if имеет его - эквивалентно, когда var ложно, быстрее, когда true.

7 голосов
/ 11 марта 2010

Чем лучше тот, который тебе нравится больше. Я бы использовал первую версию с if, но это очень личное.

4 голосов
/ 11 марта 2010

На самом деле, если вы пытаетесь определить, была ли переменная ранее установлена ​​с помощью вызова get_var, то я бы сказал, что обе формы неправильны . Python рассматривает ряд совершенно обычных значений как вычисление логического «ложь»: 0, None, [], (,), set () и {}. Допустим, var будет целым числом, а get_var () возвращает 0. Теперь, независимо от того, какую форму вы используете, get_var () будет вызываться снова и снова, даже если мы уже знаем, что var равен 0!

Существует несколько методов определения, была ли переменная определена или нет:

  • посмотрите в dict, возвращаемом globals () или localals ()

  • обернуть оператор var = var в блок try / исключением, перехватывая при ошибке NameError

  • использовать значение часового типа, например None, и инициализировать var этим значением; тогда вы можете проверить на if var is None: var = get_var() (используя 'is', а не '=='). Если вам не повезло, и None - это потенциальное значение, которое будет возвращено из get_var (), тогда вам нужно определить свое собственное специальное еще не определенное значение, используя что-то вроде NOT_DEFINED = object(), инициализировать с ним var, а затем Вы можете проверить на if var is NOT_DEFINED.

2 голосов
/ 11 марта 2010

Для меня первая идиома, использующая явный if, предпочтительнее, потому что более явная.

Однако я видел конструкцию or, на которую ссылаются как на предпочтительную / более питоническую.

Итак, с одной стороны, Explicit is better than implicit (цитата из дзен), с другой стороны, короткое выражение можно рассматривать как pythonic (хотя короче не во всех случаях эквивалентно pythonic!)

Тесно связанный вопрос SO - это самый идиоматический способ преобразования None в пустую строку , и там были указаны идиомы if и or.

2 голосов
/ 11 марта 2010

первая версия для меня более понятна. Но опять же, все зависит от вашего собственного вкуса.

1 голос
/ 11 марта 2010

Переводчик, скорее всего, выполнит их в обоих направлениях. Есть компромиссы в отношении читабельности кода. Какое утверждение легче распознать, чем оно занимается? Конечно, первое намного понятнее. Для меня, читая этот пост, мне пришлось больше думать о втором. Я бы использовал первое из-за повышенной читабельности, даже если второе утверждение немного «сексуальнее».

Надеюсь, это поможет.
-tjw

1 голос
/ 11 марта 2010

Оба будут в конечном итоге компилироваться в один и тот же код, учитывая, что или является оператором короткого замыкания (он не оценивает аргумент правой руки, если левая рука истинна).

Я бы предпочел первый, поскольку он выражает ваши намерения более четко. Второй, вероятно, более компактный.

1 голос
/ 11 марта 2010

Ни то, ни другое не верно.

Первое более понятно для того, кто читает код.

Спросите себя, если, когда вы думаете о проблеме, которую вы пытаетесь решить, концепции, которые приходят на ум, ближе к «если это, то это» или «логическое ИЛИ двух, почти, но не совсем, логическое переменные ".

1 голос
/ 11 марта 2010

Второй - более питонический, и я обычно использую это.

...