Из этих тестов нет.
if val != None:
if not (val is None):
if val is not None:
Какой из них предпочтительнее и почему?
Из этих тестов нет.
if val != None:
if not (val is None):
if val is not None:
Какой из них предпочтительнее и почему?
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.
От, Рекомендации по программированию PEP 8:
Сравнение с синглонами типа "Нет" всегда должно выполняться с помощью 'is' или 'is not', никогда не выполняются операторы равенства.
Кроме того, остерегайтесь писать "if x", когда вы действительно имеете в виду "если x не является None" - например. при проверке, является ли переменная или аргумент, по умолчанию Никому не было присвоено какое-либо другое значение. Другое значение может иметь тип (например, контейнер), который может быть ложным в булевом контексте!
PEP 8 является важным чтением для любого программиста на Python.
Любой из последних двух, поскольку val
потенциально может иметь тип, который определяет __eq__()
, чтобы возвращать true при передаче None
.
Лучшая ставка с этими типами вопросов - это то, что делает 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 - это плохая идея