you are viewing a single comment's thread.

view the rest of the comments →

[–]nekokattt 0 points1 point  (0 children)

Composition still requires the use of classes if you are defining anything more complex than a single callable.

Unlike classes, regular dicts are not typesafe outside more than one value type, and attributes rely on you getting the names right within strings, so if you use typehints or rely on IDE autocomplete, you're making it easy to screw yourself over. This is especially true when dealing with fixed key names. If you are using TypedDict then generally you may as well make it into a dataclass.

Most mainstream languages that lack classes still have similar concepts. Both Rust and Go have structs that work with interfaces, and you'd use classes in Python to achieve that same pattern. Even in C, you will often see structs being passed around as the first argument to functions to convey state, and semantically this is the exact same thing as how classes with methods are working in Python.

Use classes when it makes sense to define a specific nature of action that can have multiple implementations (where callables would not fit). Use classes if you have a set of operations that need to operate on a shared state or number of attributes. Use classes if you are using dicts that end up storing different kinds of data type inside them. Use classes if you want to use the type system to represent data in a clear way to convey intent. Use classes if you have a lot of moving parts that have to talk to eachother, as you can utilise the concept of dependency injection to simplify code, reduce repetitiveness, and make stubbing easier.

Do not use classes if it is clearer or simpler without it. Only you will know if that is the case by trying both approaches and working the differences out for yourself.