Python `if x is not None` или` if not x is None '?
Я всегда думал о версии if not x is None
, чтобы быть более ясным, но Google руководство по стилю и PEP-8 используют if x is not None
. Есть ли незначительная разница в производительности (я предполагаю, что нет), и есть ли какой-либо случай, когда один действительно не подходит (что делает другой явным победителем для моего соглашения)? *
* Я имею в виду любой синглтон, а не только None
.
... сравнить синглтоны вроде Никто. Использовать или нет.
Ответы
Ответ 1
Там нет разницы в производительности, поскольку они скомпилируются с одним и тем же байт-кодом:
Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
>>> import dis
>>> def f(x):
... return x is not None
...
>>> dis.dis(f)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 0 (None)
6 COMPARE_OP 9 (is not)
9 RETURN_VALUE
>>> def g(x):
... return not x is None
...
>>> dis.dis(g)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 0 (None)
6 COMPARE_OP 9 (is not)
9 RETURN_VALUE
Стилистически, я стараюсь избегать not x is y
. Хотя компилятор всегда будет рассматривать его как not (x is y)
, читатель может неправильно понять конструкцию как (not x) is y
. Если я пишу x is not y
, тогда нет никакой двусмысленности.
Ответ 2
Руководство по стилям Google и Python - лучшая практика:
if x is not None:
# Do something about x
Использование not x
может привести к нежелательным результатам. Увидеть ниже:
>>> x = 1
>>> not x
False
>>> x = [1]
>>> not x
False
>>> x = 0
>>> not x
True
>>> x = [0] # You don't want to fall in this one.
>>> not x
False
Возможно, вам будет интересно посмотреть, какие литералы оцениваются как True
или False
в Python:
Изменить для комментария ниже:
Я только что сделал еще несколько испытаний. not x is None
не отменяет x
сначала, а затем сравнивается с None
. На самом деле, кажется, что оператор is
имеет более высокий приоритет при использовании таким образом:
>>> x
[0]
>>> not x is None
True
>>> not (x is None)
True
>>> (not x) is None
False
Таким образом, лучше всего, по моему честному мнению, not x is None
.
Больше редактировать:
Я только что провел дополнительное тестирование и могу подтвердить, что комментарий букзора правильный. (По крайней мере, я не смог доказать это иначе.)
Это означает, что if x is not None
имеет точный результат, как if not x is None
. Я стою исправлено. Спасибо букзор.
Тем не менее, мой ответ остается в силе: используйте обычный, if x is not None
. :]
Ответ 3
Код должен быть написан, чтобы быть понятным для программиста, а второй - компилятором или интерпретатором. Конструкция "не является" больше похожа на английский, чем "не есть".
Ответ 4
Ответ проще, чем люди делают.
Нет никакого технического преимущества в любом случае, а "x is not y" - это то, что все остальные используют, что делает его явным победителем. Не имеет значения, что он "больше похож на английский" или нет; каждый использует его, а это означает, что каждый пользователь Python - даже китайские пользователи, язык которых Python не выглядит - поймет это с первого взгляда, где немного менее общий синтаксис займет пару дополнительных циклов мозга для анализа.
Не отличайтесь только ради того, чтобы быть разными, по крайней мере в этом поле.
Ответ 5
Python if x is not None
или if not x is None
?
TL;DR: Компилятор байт-кода анализирует их как на x is not None
- поэтому для удобства чтения используйте if x is not None
.
читаемость
Мы используем Python, потому что мы ценим такие вещи, как удобочитаемость, удобство использования и правильность различных парадигм программирования по производительности.
Python оптимизирует для удобочитаемости, особенно в этом контексте.
Разбор и компиляция байт-кода
not
связывается более слабо, чем is
, поэтому здесь нет никакой логической разницы. См. Документацию :
Операторы is
и is not
проверяют идентичность объекта: x is y
истинно тогда и только тогда, когда x и y - один и тот же объект. x is not y
дает обратное значение истинности.
is not
специально предусмотрен для Python grammar в качестве улучшения читаемости для языка:
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
И это тоже унитарный элемент грамматики.
Конечно, он не анализируется одинаково:
>>> import ast
>>> ast.dump(ast.parse('x is not None').body[0].value)
"Compare(left=Name(id='x', ctx=Load()), ops=[IsNot()], comparators=[Name(id='None', ctx=Load())])"
>>> ast.dump(ast.parse('not x is None').body[0].value)
"UnaryOp(op=Not(), operand=Compare(left=Name(id='x', ctx=Load()), ops=[Is()], comparators=[Name(id='None', ctx=Load())]))"
Но тогда байт-компилятор фактически переведет not ... is
в is not
:
>>> import dis
>>> dis.dis(lambda x, y: x is not y)
1 0 LOAD_FAST 0 (x)
3 LOAD_FAST 1 (y)
6 COMPARE_OP 9 (is not)
9 RETURN_VALUE
>>> dis.dis(lambda x, y: not x is y)
1 0 LOAD_FAST 0 (x)
3 LOAD_FAST 1 (y)
6 COMPARE_OP 9 (is not)
9 RETURN_VALUE
Итак, для удобства чтения и использования языка, как он был предназначен, используйте is not
.
Чтобы не использовать его не мудрый.
Ответ 6
Оператор is not
предпочтителен по сравнению с отрицанием результата is
по стилистическим причинам. "if x is not None:
" читается точно так же, как на английском, но "if not x is None:
" требует понимания приоритета оператора и не читается, как английский.
Если есть разница в производительности, мои деньги находятся на is not
, но это почти наверняка не является мотивацией для решения предпочесть эту технику. Очевидно, что это зависит от реализации. Поскольку is
не является переопределяемым, в любом случае должно быть легко оптимизировать любое различие.
Ответ 7
Лично я использую
if not (x is None):
который сразу понимается без двусмысленности каждым программистом, даже теми, кто не разбирается в синтаксисе Python.
Ответ 8
if not x is None
больше похож на другие языки программирования, но if x is not None
определенно звучит более ясно (и более грамматически корректно на английском языке) для меня.
Это говорит, что для меня это кажется более предпочтительным.
Ответ 9
Я бы предпочел более читаемую форму x is not y
чем я подумал бы, как в конечном итоге написать приоритет обработки кода операторами, чтобы получить гораздо более читаемый код.
Ответ 10
x = None
if not x: print x, '2.?'
Нет 2.?
from __future__ import print_function
if(not x): print(x, '3.?')
(Нет, '3.?')
Ответ 11
Попробуйте следующее:
if x != None:
# do stuff with x