> So it's really pick your poison; either the child controls the call, at the risk of doing it wrong or not at all, or it doesn't but then certain things become impossible.
CL lets you do both in various ways: the typical way to define a constructor is an :AFTER method that just sets the slots (fields in other languages) of the object and having a lot of behavior in constructors is unusual. You can also define an :AROUND method which would let a child class override the arguments passed to the constructor, with the downside that you can forget to CALL-NEXT-METHOD.
However, CL's approach to object-orientation is pretty radically different from Python's. It's not a "kingdom of nouns" system where classes contain behavior and state but rather classes can contain state and behaviors are on equal footing with classes in the form of generic functions. (If you aren't familiar, I found skimming chapters 16+17 here[1] very enlightening when I was first learning CL). Classes in CL frequently don't contain any state at all and merely exist to pick out an implementation of a generic function to be used. Generic functions establish a web of relations between classes because they dispatch on every argument and not just a "this" parameter.
[1]: https://gigamonkeys.com/book/