In Python, type checking can compare an object's type with an expected type before an operation proceeds. Types are objects: `type("Hello") == type("Goodbye")` is true, while `type("Hello") == type(5)` is false. A function or method can use that comparison to reject an unexpected value. section 17.2
A typed list is one practical use. It can take an example element to establish the allowed type, check its initial elements, and raise `TypeError` on a mismatch. Its `__setitem__` method can check each later indexed assignment before storing the value; `__getitem__` provides indexed access. section 17.8
class TypedList:
def __init__(self, example_element, initial_list=[]):
self.type = type(example_element)
if not isinstance(initial_list, list):
raise TypeError("Second argument of TypedList must "
"be a list.")
for element in initial_list:
self.__check(element)
self.elements = initial_list[:]
def __check(self, element):
if type(element) != self.type:
raise TypeError("Attempted to add an element of "
"incorrect type to a typed list.")
def __setitem__(self, i, element):
self.__check(element)
self.elements[i] = element
def __getitem__(self, i):
return self.elements[i]
The `TypedList` implementation puts the exact-type comparison in `__check`, which both initialization and indexed assignment call. Notice that it separately uses `isinstance` to require a list as its initial collection. section 17.8
Check every route by which values can enter a collection. For a string-only dictionary, overriding `__setitem__` handles assignments, but construction from key-value pairs or another dictionary can bypass it. Override `__init__` too, then inspect both keys and values. section 17.11
Type checks are not always the best default. Duck typing accepts an object that supports the needed operation without requiring a particular class; it favors flexibility, readable code, and testing. For larger codebases, explicit type hints verified by a type checker offer another way to catch mistakes. section 17.4




