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