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