Instead of a complicated, long expression as one statement in Python, it tends to be better to break it into several. Code is much clearer, if a few lines longer.
Keyword args in Python help a lot, but they need a mechanism to make sure caller doen't accidentally provide value for a keyword argument.
Further, hiding arguments as object state is also often a recipe for bugs, but it's also often the right way to go.
Programming is difficult.
@liw In some Python code I've seen a pattern of taking **kwargs and using kwargs.pop to extract each allowed name. If you do that, then excess positional arguments will raise TypeError instead of being quietly assigned to keyword arguments. Of course then you have to turn any KeyError raised by pop into a TypeError yourself, and often you'd want to raise a TypeError if kwargs isn't empty after you've popped all the arguments you expected. I agree, programming is hard. 😅