Why do I really need a class, when:
- Instance fields can be added and removed at runtime
- Private fields and methods are not actually private ("we're all consenting adults here")
- No pattern matching on types and `if isinstance(foo, Bar):` is an anti-pattern because it's a duck-typed language
- Interfaces are neither available nor necessary due to late binding. Abstract Base Classes are the closest thing to an interface, but they're also unnecessary because again, it's duck-typed.
- Inheritance is widely considered to be a mistake ("Prefer composition over inheritance" etc)
- Classes tend to complicate testing
I can use classes to write custom data structures, I guess, but in a language as high-level as Python, I can just model trees and graphs with dicts. If I need a more performant data structure, I'm not writing it in Python in the first place.
I've seen some very experienced Pythonistas recommend using namedtuple instead of classes for most use cases, and I tend to agree with them. That gets you immutability as well as dot notation for accessing fields.
Clojure programmers seem perfectly happy with just lists and maps, and after experiencing that, classes feel like a bolted-on misfeature in Python.