Что делает оператор " is " в Python?

Я (возможно, ошибочно) думал, что is оператор выполняет сравнение id ().

>>> x = 10
>>> y = 10
>>> id(x)
1815480092
>>> id(y)
1815480092
>>> x is y
True

однако, с val is not None кажется, что это не так просто.

>>> id(not None)
2001680
>>> id(None)
2053536
>>> val = 10
>>> id(val)
1815480092
>>> val is not None
True

тогда, что делает оператор "is"? Это просто сравнение идентификаторов объектов, которое я предположил? Если так, то val is not None интерпретируется в Python, как not (val is None)?

3 ответов


вы пропустили, что is not оператор слишком.

без is очередное not оператор возвращает логическое значение:

>>> not None
True

not None является, таким образом, обратным булевым "значением"None. В логическом контексте None ложно:

>>> bool(None)
False

так not None логическое True.

и None и True также являются объектами, и оба имеют адрес памяти (значение id() возврат для CPython реализация Python):

>>> id(True)
4440103488
>>> id(not None)
4440103488
>>> id(None)
4440184448

is тесты, Если две ссылки указывают на тот же объект; если что-то является тем же объектом, оно будет иметь то же самое id() как хорошо. is возвращает логическое значение, True или False.

is not в противоположность is оператора. Это эквивалент not (op1 is op2), в один оператор. Он должен!--25-->не читать как op1 is (not op2) здесь:

>>> 1 is not None     # is 1 a different object from None?
True
>>> 1 is (not None)   # is 1 the same object as True?
False

в дополнение к Martijn Питерс ответ None, True и False одноэлементных. Существует только один экземпляр каждого из этих значений, поэтому безопасно использовать is чтобы проверить их..

>>> id(True)
8851952
>>> id(False)
8851920
>>> id(None)
8559264
>>> id(not None)
8851952
>>> id(1 == 0)
8851920
>>> id(1 == 1)
8851952

Python пытается эмулировать синтаксис английского языка, чтобы сделать его более читаемым человеком, но в этом случае приоритет оператора немного запутан.

>>> val is not None
True

на английском языке, мы просим, если val не имеет значения, которое представлено тем же объектом, что и None. В приведенном выше примере val=10, поэтому ответ (правильно)True.

однако с логической, синтаксической точки зрения вы разбили утверждение слово в слово и предположили это будет:

>>> val is (not None)
False

где, когда, заключенные в соответствующие patentheses, возвращает ожидаемый результат (False).

как указывает @Martijn Pieters,is not оператор в своем собственном праве и это единственный оператор на работе здесь.

если вы хотите написать его как неоднозначный оператор, используя только операторы, не содержащие пробелов, вы можете написать:

>>> not (val is None)
True

но это не так, как вы хотели "сказать" целевое заявление на английском языке, или, возможно, даже написать его в псевдокоде.