On Wed, Jul 17, 2019 at 3:58 AM Ian Kelly <ian.g.ke...@gmail.com> wrote: > > On Tue, Jul 16, 2019 at 1:21 AM Chris Angelico <ros...@gmail.com> wrote: > > > > On Tue, Jul 16, 2019 at 3:32 PM Ian Kelly <ian.g.ke...@gmail.com> wrote: > > > > > > Just using super() is not enough. You need to take steps if you want to > > > ensure that you class plays nicely with MI. For example, consider the > > > following: > > > > > > class C1: > > > def __init__(self, name): > > > self._name = name > > > > > > class C2(C1): > > > def __init__(self, name, value): > > > super().__init__(name) > > > self._value = value > > > > > > This usage of super is just fine for the single-inheritance shown here. > But > > > there are two reasons why this cannot be neatly pulled into an MI > > > hierarchy. Can you spot both of them? > > > > Well, obviously it's violating LSP by changing the signature of > > __init__, which means that you have to be aware of its position in the > > hierarchy. If you want things to move around smoothly, you HAVE to > > maintain a constant signature (which might mean using *args and/or > > **kwargs cooperatively). > > That's pretty close to what I had in mind. Many people treat __init__ as a > constructor (I know, it's not)
If you consider __new__ to be the constructor, and __init__ to be an implementation detail of how the constructor initializes the object, then it comes to the same thing anyway. > and so long as you're following that > doctrine it's not really an LSP violation. But anything else that gets > worked into an MI hierarchy has to somehow be compatible with both of these > method signatures while also adding whatever new parameters it needs, which > is a problem. The usual advice for working with this is to use **kwargs > cooperatively as you suggested. *args doesn't work as well because every > class needs to know the absolute index of every positional parameter it's > interested in, and you can't just trim off the end as you go since you > don't know if the later arguments have been consumed yet. With **kwargs you > can just pop arguments off the dict as you go. Yeah, makes sense. I'd advocate a slightly weakened form of LSP-style equivalence: the function signatures don't have to be *identical*, but they do have to be built with compatibility in mind. ChrisA -- https://mail.python.org/mailman/listinfo/python-list