Пітон 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.