Python `если х не None` или` если не х None`? - PullRequest
629 голосов
/ 26 апреля 2010

Я всегда думал, что версия if not x is None более понятна, но в руководстве по стилям Google и PEP-8 оба используют if x is not None. Есть ли небольшая разница в производительности (я предполагаю, что нет), и есть ли какой-то случай, когда один действительно не подходит (что делает другого явным победителем в моем соглашении)? *

* Я имею в виду любой синглтон, а не просто None.

... сравнивать синглеты вроде Никто. Использование есть или нет.

Ответы [ 10 ]

883 голосов
/ 26 апреля 2010

Нет разницы в производительности, так как они компилируются в один и тот же байт-код:

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, тогда двусмысленности не будет.

155 голосов
/ 26 апреля 2010

Как 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. :]

119 голосов
/ 26 апреля 2010

Код должен быть написан в первую очередь понятным для программиста, а затем для компилятора или интерпретатора. Конструкция "не" больше похожа на английский, чем "не есть".

29 голосов
/ 26 апреля 2010

Ответ проще, чем его делают люди.

Технического преимущества в любом случае нет, и "x is y" - это то, что все остальные используют , что делает его явным победителем. Неважно, что это «больше похоже на английский» или нет; каждый использует его, что означает, что каждый пользователь Python - даже китайские пользователи, чей язык Python совсем не похож на это - поймет это с первого взгляда, где немного менее распространенный синтаксис потребует несколько дополнительных мозговых циклов для анализа.

Не отличайтесь только ради того, чтобы отличаться, по крайней мере, в этой области.

24 голосов
/ 20 июля 2015

Python if x is not None или if not x is None?

TLDR: компилятор байт-кода анализирует их как x is not None - поэтому для удобства чтения используйте if x is not None.

читаемость

Мы используем Python, потому что мы ценим такие вещи, как удобочитаемость, удобство использования и правильность различных парадигм программирования, а не производительность.

Python оптимизирован для удобства чтения, особенно в этом контексте.

Разбор и компиляция байт-кода

not связывается слабее , чем is, поэтому здесь нет логической разницы. См. документацию :

Операторы is и is not проверяют идентичность объекта: x is y имеет значение true тогда и только тогда, когда x и y - один и тот же объект. x is not y дает значение обратной истинности.

is not специально предусмотрен в Python грамматика как улучшение читаемости для языка:

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.

Не использовать его не является мудрым.

9 голосов
/ 26 апреля 2010

Оператор is not предпочтительнее, чем отрицание результата is по стилистическим соображениям. «if x is not None:» читается так же, как английский, но «if not x is None:» требует понимания приоритета оператора и не читает как английский.

Если есть разница в производительности, мои деньги идут на is not, но это почти наверняка не является мотивацией для решения о выборе этой техники. Очевидно, это будет зависеть от реализации. Поскольку is не может быть переопределено, все равно будет легко оптимизировать любые различия.

7 голосов
/ 26 июня 2016

Лично я пользуюсь

if not (x is None):

, что понимается сразу, без двусмысленности всеми программистами, даже теми, кто не разбирается в синтаксисе Python.

1 голос
/ 26 апреля 2010

if not x is None больше похож на другие языки программирования, но if x is not None определенно звучит для меня более четко (и более грамматически правильно на английском).

Тем не менее, мне кажется, что это больше для меня предпочтение.

0 голосов
/ 24 сентября 2015

Я бы предпочел более читаемую форму x is not y чем я мог бы подумать, как в конечном итоге написать код, обрабатывающий приоритет операторов, чтобы создать гораздо более читаемый код.

0 голосов
/ 16 июля 2015

Попробуйте это:

    if x != None:
       # do stuff with x
...