mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
bpo-43325: Add FAQ entry for identity tests (GH-25168)
This commit is contained in:
parent
35715d1e72
commit
f8775e4f72
2 changed files with 89 additions and 3 deletions
|
@ -1701,6 +1701,93 @@ to the object:
|
|||
13891296
|
||||
|
||||
|
||||
When can I rely on identity tests with the *is* operator?
|
||||
---------------------------------------------------------
|
||||
|
||||
The ``is`` operator tests for object identity. The test ``a is b`` is
|
||||
equivalent to ``id(a) == id(b)``.
|
||||
|
||||
The most important property of an identity test is that an object is always
|
||||
identical to itself, ``a is a`` always returns ``True``. Identity tests are
|
||||
usually faster than equality tests. And unlike equality tests, identity tests
|
||||
are guaranteed to return a boolean ``True`` or ``False``.
|
||||
|
||||
However, identity tests can *only* be substituted for equality tests when
|
||||
object identity is assured. Generally, there are three circumstances where
|
||||
identity is guaranteed:
|
||||
|
||||
1) Assignments create new names but do not change object identity. After the
|
||||
assignment ``new = old``, it is guaranteed that ``new is old``.
|
||||
|
||||
2) Putting an object in a container that stores object references does not
|
||||
change object identity. After the list assignment ``s[0] = x``, it is
|
||||
guaranteed that ``s[0] is x``.
|
||||
|
||||
3) If an object is a singleton, it means that only one instance of that object
|
||||
can exist. After the assignments ``a = None`` and ``b = None``, it is
|
||||
guaranteed that ``a is b`` because ``None`` is a singleton.
|
||||
|
||||
In most other circumstances, identity tests are inadvisable and equality tests
|
||||
are preferred. In particular, identity tests should not be used to check
|
||||
constants such as :class:`int` and :class:`str` which aren't guaranteed to be
|
||||
singletons::
|
||||
|
||||
>>> a = 1000
|
||||
>>> b = 500
|
||||
>>> c = b + 500
|
||||
>>> a is c
|
||||
False
|
||||
|
||||
>>> a = 'Python'
|
||||
>>> b = 'Py'
|
||||
>>> c = b + 'thon'
|
||||
>>> a is c
|
||||
False
|
||||
|
||||
Likewise, new instances of mutable containers are never identical::
|
||||
|
||||
>>> a = []
|
||||
>>> b = []
|
||||
>>> a is b
|
||||
False
|
||||
|
||||
In the standard library code, you will see several common patterns for
|
||||
correctly using identity tests:
|
||||
|
||||
1) As recommended by :pep:`8`, an identity test is the preferred way to check
|
||||
for ``None``. This reads like plain English in code and avoids confusion with
|
||||
other objects that may have boolean values that evaluate to false.
|
||||
|
||||
2) Detecting optional arguments can be tricky when ``None`` is a valid input
|
||||
value. In those situations, you can create an singleton sentinel object
|
||||
guaranteed to be distinct from other objects. For example, here is how
|
||||
to implement a method that behaves like :meth:`dict.pop`::
|
||||
|
||||
_sentinel = object()
|
||||
|
||||
def pop(self, key, default=_sentinel):
|
||||
if key in self:
|
||||
value = self[key]
|
||||
del self[key]
|
||||
return value
|
||||
if default is _sentinel:
|
||||
raise KeyError(key)
|
||||
return default
|
||||
|
||||
3) Container implementations sometimes need to augment equality tests with
|
||||
identity tests. This prevents the code from being confused by objects such as
|
||||
``float('NaN')`` that are not equal to themselves.
|
||||
|
||||
For example, here is the implementation of
|
||||
:meth:`collections.abc.Sequence.__contains__`::
|
||||
|
||||
def __contains__(self, value):
|
||||
for v in self:
|
||||
if v is value or v == value:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
Modules
|
||||
=======
|
||||
|
||||
|
|
|
@ -661,9 +661,8 @@ operators, not just comparisons.
|
|||
|
||||
The comparison operators ``in`` and ``not in`` check whether a value occurs
|
||||
(does not occur) in a sequence. The operators ``is`` and ``is not`` compare
|
||||
whether two objects are really the same object; this only matters for mutable
|
||||
objects like lists. All comparison operators have the same priority, which is
|
||||
lower than that of all numerical operators.
|
||||
whether two objects are really the same object. All comparison operators have
|
||||
the same priority, which is lower than that of all numerical operators.
|
||||
|
||||
Comparisons can be chained. For example, ``a < b == c`` tests whether ``a`` is
|
||||
less than ``b`` and moreover ``b`` equals ``c``.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue