не тест None в Python [дубликат]
этот вопрос уже есть ответ здесь:
питон `если X не нет " или " если не Х нет`?
10 ответов
из этих тестов нет ни одного.
if val != None:
if not (val is None):
if val is not None:
какой из них предпочтительнее и почему?
4 ответов:
if val is not None: # ...- это подходящие для Python идиома для тестирования, что переменная не установлена до
None. Эта идиома имеет особое использование в случае объявление ключевых функций с параметрами по умолчанию.isпроверяет идентичность в Python. Потому что есть один и только один экземплярNoneприсутствует в запущенном скрипте/программе Python,isявляется оптимальным тестом для этого. Как Johnsyweb указывает, это обсуждается в PEP 8 в разделе "Программирование Рекомендации."что касается того, почему это предпочтительнее
if not (val is None): # ...это просто часть Дзен питона: "читабельность имеет значение."Хороший питон часто близок к хорошему псевдокод.
От, Рекомендации По Программированию,PEP 8:
сравнения с синглетами, такими как None, всегда должны выполняться "есть" или "нет", никогда операторы равенства.
кроме того, остерегайтесь писать "если x", когда вы действительно имеете в виду "если x нет" -- например, при проверке того, является ли переменная или аргумент, который по умолчанию Ни один не был установлен на другое значение. Другое значение может иметь тип (например, контейнер), который может быть ложным в a логический контекст!
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.как указано в других ответах, используя
!=при сравнении ни с одной это плохая идея
Comments