Питон 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
истинно тогда и только тогда, когда 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
.
Не использовать это не разумно.
is not
оператор сам по себе. Как!=
. Если вы предпочитаете,not x is None
то вы должны также предпочестьnot a == b
болееa != b
.