Inheritance lets a class reuse behavior from another class. Put the base class in parentheses after the new class’s name: `class Circle(Shape):`. A circle can then use methods defined on `Shape` while adding its own attributes and methods. section 15.6
class Shape:
def __init__(self, x, y):
self.x = x
self.y = y
class Square(Shape): #1
def __init__(self, side=1, x=0, y=0):
super().__init__(x, y) #2
self.side = side
class Circle(Shape): #3
def __init__(self, r=1, x=0, y=0):
super().__init__(x, y) #2
self.radius = r
#1 Says Square inherits from Shape
#2 Must call __init__ method of Shape
#3 Says Circle inherits from Shape
The shared `Shape` initializer sets `x` and `y`; `Square` and `Circle` add their own dimensions. Each subclass explicitly calls `super().__init__(x, y)`. Without that call, these instances would not get their position attributes from this initializer. section 15.6
Use a parent method
Give `Shape` a `move` method that updates `x` and `y`. Then `c = Circle(1); c.move(3, 4)` leaves `c.x` at `3` and `c.y` at `4`, even though `Circle` defines no `move` method of its own. Python finds it farther up the inheritance hierarchy. section 15.6 section 15.8
Keep these attribute rules in mind:
- An inherited method works on the subclass instance itself. If parent and child methods both assign `self.x`, they refer to that instance’s same `x` attribute—not to separate parent and child instances. section 15.7
- Class variables are inherited, but assignment can hide rather than change them: assigning `C.z` creates a variable on `C` without changing `P.z`; assigning `c.z` creates an instance variable. section 15.7
Inheritance also works with built-in types. Subclassing `list` supplies existing list operations while letting a typed-list class check assignments in `__setitem__`. For a string-only dictionary, overriding `__setitem__` alone is insufficient: construction from another dictionary or key-value pairs can bypass that check, so `__init__` needs attention too. section 17.9.1 section 17.11
Exception classes form another useful hierarchy. `class MyError(Exception): pass` creates an exception that can be raised and caught. Catch specific subclasses before broader parents: an `except LookupError` placed before `except IndexError` catches an `IndexError` first, leaving the narrower clause unused. section 14.2.4 section 14.2.7
To inspect a hierarchy, use `issubclass` for classes and `isinstance` for instances; a class’s `__bases__` lists its direct bases. Inheritance is most useful when the base class can carry substantial shared behavior and subclasses need little repeated code. section 17.3 section 15.14.2


















