Что лучше?
if not var:
var = get_var()
(или) var = var или get_var ()
Кроме того, как мне узнать лучшее из двух?
edit:
Еще один вариант от Стива,
var = var if var else get_var()
Что лучше?
if not var:
var = get_var()
(или) var = var или get_var ()
Кроме того, как мне узнать лучшее из двух?
edit:
Еще один вариант от Стива,
var = var if var else get_var()
Лучше тот, который тебе больше нравится. Я бы использовал первую версию с if
, но это очень личное.
Когда два варианта стилей настолько близки стилистически, я использую 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
.
timeit
- это способ зафиксировать общую сумму их (наших) усилий для принятия спорного решения.
- person Alex Martelli; 11.03.2010
x=x
не оптимизируется компилятором Python, который на самом деле является супер-простым компилятором, поэтому тот факт, что короткое замыкание приводит к эквиваленту var=var
, не делает последний бесплатным! -)
- person Alex Martelli; 11.03.2010
who would imagine Alex as an advocate for micro-optimization ?
) и, прежде всего, облегчение, которое он предоставил на серьезной, но тем не менее анекдотической теме. Когда дело доходит до Python, Алекс серьезно относится ко всему, по крайней мере, по умолчанию.
- person mjv; 11.03.2010
На самом деле, если вы пытаетесь определить, была ли ранее установлена переменная var с помощью вызова get_var, я бы сказал, что обе формы неверны. Python обрабатывает ряд совершенно обычных значений как вычисляющих логическое значение false: 0, None, [], (,), set () и {}. Итак, предположим, что var будет целым числом, а get_var () вернет 0. Теперь, независимо от того, какую форму вы используете, get_var () будет вызываться снова и снова, даже если мы уже знаем, что var равно 0!
Существует несколько методов определения того, была ли определена переменная:
посмотрите в слове, возвращаемом globals () или locals ()
заключить оператор var = var
в блок try / except, захватить NameError
используйте контрольное значение, например None, и инициализируйте var этим значением; тогда вы можете проверить if var is None: var = get_var()
(используя 'is', а не '=='). Если вам не повезло, и None - это потенциальное значение, которое может быть возвращено get_var (), вам нужно будет определить свое собственное специальное еще не определенное значение, используя что-то вроде NOT_DEFINED = object()
, инициализировать var с его помощью, а затем вы можете тест на if var is NOT_DEFINED
.
Для меня первая идиома, использующая явное if, предпочтительнее, потому что она более явная.
Однако я видел, что конструкция or упоминается как предпочтительная / более питоническая.
Итак, с одной стороны, Explicit is better than implicit
(цитирование Дзэн), с другой стороны, короткое выражение можно рассматривать как питоническое (хотя короче не во всех случаях эквивалентно питоническому!)
Тесно связанный вопрос SO - это самый идиоматический способ преобразования None в пустую строку, и там были перечислены идиомы if и or.
первая версия мне более интуитивно понятна. Но опять же, все дело в вашем собственном вкусе.
Второй более питонический, и я обычно его использую.
if
не является Pythonic? что составляет Pythonic?
- person ghostdog74; 11.03.2010
var
оказывается логическим. В противном случае, вероятно, нет, хотя контекст может изменить мое мнение.
- person Steve314; 11.03.2010
Ни то, ни другое не так.
Первый вариант более понятен тем, кто читает код.
Спросите себя, когда вы думаете о проблеме, которую пытаетесь решить, идеи, которые приходят вам на ум, ближе к «если это, то то» или «логическому ИЛИ двух почти, но не совсем логических переменных».
Оба в конечном итоге будут скомпилированы в один и тот же код, учитывая, что или является оператором короткого замыкания (он не оценивает аргумент правой руки, если левая сторона истинна).
Я бы предпочел первый, так как он более четко выражает ваши намерения. Второй, наверное, более компактный.
Интерпретатор, скорее всего, выполнит их в обоих направлениях. Есть компромиссы относительно читабельности кода. Какое утверждение легче распознать, что оно делает? Конечно, первое гораздо яснее. Мне, читая этот пост, пришлось больше думать о втором. Я бы использовал первое из-за большей читабельности, даже если второе утверждение немного «сексуальнее».
Надеюсь это поможет.
-tjw
var = var if var else getvar ()
- в данном случае не обязательно рекомендация, это просто еще один вариант. - person Steve314   schedule 11.03.2010var = get_new_var()
? - person PaulMcG   schedule 12.03.2010