| Pitfall | Solution | |---------|----------| | Mutable default arguments | def __init__(self, items=None): if items is None: items = [] | | Forgetting to call super().__init__() in multiple inheritance | Always use super() in every class that participates in cooperative inheritance | | Using __slots__ and then wondering why dynamic attributes fail | Understand __slots__ disables __dict__ | | Deep inheritance > 3 levels | Prefer composition or interfaces (ABCs/protocols) | | Overusing metaclasses | 99% of needs solved by class decorators or __init_subclass__ (Python 3.6+) |
def add_repr(cls): def __repr__(self): return f"cls.__name__(self.__dict__)" cls.__repr__ = __repr__ return cls python 3 deep dive part 4 oop
class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y | Pitfall | Solution | |---------|----------| | Mutable
Now you can discover and execute all plugins dynamically. 'y') def __init__(self
class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y
Contrast with ABC: no explicit inheritance, just "looks like a duck".