🐍 Python - Equality
Updated at 2018-06-10 22:00
is
checks for identity while ==
checks for equality.
a = [1, 2, 3]
b = a
c = list(a)
assert a == b
assert a is b
assert a == c
assert a is not c
Any content or value makes an object truthy.
assert not False
assert True
assert not None # None is falsy
assert not () # empty tuple is falsy
assert (None,) # any content makes tuple truthy
assert not [] # empty list is falsy
assert [None] # any content make list truthy
assert not set() # empty set is falsy
assert {None} # any content makes set truthy
assert not {} # empty dict is falsy
assert {'key': None} # any content makes dict truthy
assert not '' # empty str is falsy
assert ' ' # any content makes str truthy
assert not 0 # zero integer is falsy
assert -123 and 123 # non-zero integers are truthy
assert not 0.0 # zero float is falsy
assert -.1 and 12.3 # non-zero floats are truthy
a == b
is syntactical sugar for a.
eq(b)``
Always use is
to check for singletons like None
. is
is less error prone and faster as it can't be overloaded like ==
.
from typing import Optional
def greet(name: Optional[str] = None):
if name is None:
return 'Hello!'
else:
return f'Hello, {name}!'
assert greet() == 'Hello!'
assert greet('Ruksi') == 'Hello, Ruksi!'
Never use is
with strings or integers. It usually works because of interning, but is undocumented implementation quirk.
s1 = 'ABC'
s2 = 'ABC'
assert s1 is s2 # BAD, never do this even if it works for now
Prefer isinstance(obj, cls)
over type(obj) == cls
. And make sure cls
is always an abstract class which's metaclass derives from abc.ABCMeta
. There are plenty of useful abstract classes in typing
and numbers
, although int
and float
are usually the best.
import numbers
from typing import Callable, Collection, Container, Hashable, \
Iterable, MutableSequence, Sequence, Sized
assert isinstance(list(), Collection)
assert isinstance(list(), Sized)
assert isinstance(list(), Container)
assert isinstance(list(), Sequence)
assert isinstance(list(), MutableSequence)
assert isinstance(list(), Iterable)
assert not isinstance(list(), Hashable)
def greet() -> str:
return 'Hello!'
assert isinstance(greet, Callable)
assert isinstance(lambda x: x + 1, Callable)
assert isinstance(123, int)
assert not isinstance(123, float)
assert isinstance(1.23, float)
assert not isinstance(1.23, int)
assert isinstance(123, numbers.Number)
assert isinstance(123, numbers.Complex)
assert isinstance(123, numbers.Real)
assert isinstance(123, numbers.Rational) # different than decimal.Decimal
assert isinstance(123, numbers.Integral)
assert isinstance(1.23, numbers.Number)
assert not isinstance(1.23, numbers.Integral)
assert isinstance(True, numbers.Number) # Booleans are numbers 1 and 0
assert isinstance(False, numbers.Number)
Source
- Python Tricks The Book, Dan Bader
- Fluent Python, Luciano Ramalho