Нет теста на Python

Из этих тестов нет.

if val != None:

if not (val is None):

if val is not None:

Какой из них предпочтительнее и почему?

Ответ 1

if val is not None:
    # ...

- это идиома Pythonic для проверки того, что переменная не установлена ​​на None. Эта идиома имеет особое применение в случае объявления функций ключевых слов с параметрами по умолчанию. is проверяет идентификатор в Python. Поскольку в запущенной программе Python script/присутствует один и только один экземпляр None, is является оптимальным для этого. Как указывает Johnsyweb, это обсуждается в PEP 8 в разделе "Рекомендации по программированию".

Что касается того, почему это предпочтительнее

if not (val is None):
    # ...

это просто часть Zen of Python: "Чтение рассчитывается". Хороший Python часто близок к хорошему pseudocode.

Ответ 2

От, Рекомендации по программированию PEP 8:

Сравнение с синглонами типа "Нет" всегда должно выполняться с помощью 'is' или 'is not', никогда не выполняются операторы равенства.

Кроме того, остерегайтесь писать "if x", когда вы действительно имеете в виду "если x не является None" - например. при проверке, является ли переменная или аргумент, по умолчанию Никому не было присвоено какое-либо другое значение. Другое значение может иметь тип (например, контейнер), который может быть ложным в булевом контексте!

PEP 8 является важным чтением для любого программиста на Python.

Ответ 3

Любой из последних двух, поскольку val потенциально может иметь тип, который определяет __eq__(), чтобы возвращать true при передаче None.

Ответ 4

Лучшая ставка с этими типами вопросов - это то, что делает python. Модуль dis невероятно информативен:

>>> def f(val):
...   if val != None:
...     return True
...   return False
...
>>> def g(val):
...   if not (val is None):
...     return True
...   return False
...
>>> def h(val):
...   if val is not None:
...     return True
...   return False
...
>>> import dis
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (val)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               3 (!=)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_GLOBAL              1 (True)
             15 RETURN_VALUE

  4     >>   16 LOAD_GLOBAL              2 (False)
             19 RETURN_VALUE
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (val)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_GLOBAL              1 (True)
             15 RETURN_VALUE

  4     >>   16 LOAD_GLOBAL              2 (False)
             19 RETURN_VALUE
>>> dis.dis(h)
  2           0 LOAD_FAST                0 (val)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_GLOBAL              1 (True)
             15 RETURN_VALUE

  4     >>   16 LOAD_GLOBAL              2 (False)
             19 RETURN_VALUE

Обратите внимание, что последние два случая сводятся к одной и той же последовательности операций (python читает not (val is None) и использует оператор is not). Первый использует оператор != при сравнении с None.

Как указано в других ответах, использование != при сравнении с None - это плохая идея