`isinstance(object, class)` checks whether an object is an instance of a class. The check includes inheritance: an instance of a subclass also passes a check against its base class. Use it when a function or method needs to validate an expected type. section 17.3
A subclass passes its base-class check
class Base: pass class Child(Base): pass isinstance(Child(), Child) # True isinstance(Child(), Base) # True isinstance(Base(), Child) # False section 17.3
Type checks can guard inputs and container contents:
- A string-only dictionary can check keys and values with `isinstance(value, str)` and raise `TypeError` for a mismatch. section 17.11.2
- A typed-list class can obtain an expected class with `type(example_element)`, then check initial elements with `isinstance`. A later version uses `type(element) != self.type` for an exact-type check instead. section 17.8
""" Create a dictionary that allows only strings for keys and values"""
class StringDict(dict):
def __setitem__(self, key, value):
if not isinstance(key, str):
raise TypeError('key is not a string') #1
if not isinstance(value, str):
raise TypeError('value is not a string')
super().__setitem__(key, value)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
key_error = any(not isinstance(_, str)
for _ in self.keys()) #2
if key_error:
raise TypeError('key is not a string')
value_error = any(not isinstance(_, str)
for _ in self.values()) #2
if value_error:
raise TypeError('value is not a string')
The string-only dictionary checks assignments in `__setitem__`. Its initializer also checks the populated dictionary, because initial data may arrive as key-value pairs or another dictionary. `any` flags a non-string key or value. section 17.11.2
For instances, prefer `isinstance` when subclasses should count. `issubclass` instead checks relationships between classes. Before adding an explicit type check, consider whether the operation itself can handle an unsuitable object. section 17.3

