2018-05-28 9:44 GMT+02:00 Michael Lohmann <mial.lohm...@gmail.com>: > >> I'd say NOT wanting to call an __init__ method of a superclass is a >> rather uncommon occurence. It's generally a huge error. So I think >> it's worth not accomodating that. > > I will give you an example then where I am absolutely fine with calling > super().__init__ in all classes and describe why I am not really satisfied > with the current status. (It is from my email from yesterday 17:19 GMT): > >> What bugs me is that in my example from yesterday ( >> class Aardvark: >> def __init__(self, quantity, **kwargs): >> print("There is some quantity:", quantity) >> # I actually don’t care about **kwargs and just hand them on >> super().__init__(**kwargs) >> >> class Clever: >> def __init__(self, cleverness=1): >> print("You are %d clever“ % cleverness) >> >> class Ethel(Aardvark, Clever): >> """Ethel is a very clever Aardvark""" >> def __init__(self): >> super().__init__(quantity="some spam", cleverness=1000) >> ) if you want to instantiate an Aardvark directly there is NO WAY EVER that >> you could give him ANY kwargs. So why should the __init__ indicate something >> else? Well, just to make the MRO work. All I want is to make it as obvious >> as possible that an Aardvark only takes `quantity` as input, but is fully >> "cooperative" with other classes if it is in the middle of the MRO (by which >> I mean that it will automatically call the __init__ and hand on any kwargs >> it didn’t expect to a class from a different branch of the class hierarchy).
This is more an issue with your Ethel class. In *normal* subclassing, it's init would look like: class Ethel(Aardvark, Clever): def __init__(self, **kwargs): super().__init__(**kwargs) and you'd instantiate it like: e = Ethel(quantity="some spam", cleverness=1000) or even (because keyword argument order doesn't matter): e = Ethel(cleverness=1000, quantity="some spam") Because don't forget: assert isinstance(e, Ethel) assert isinstance(e, Aardvark) assert isinstance(e, Clever) will all pass perfectly fine. It's not just an Ethel or an Aardvark, it's also a Clever. (which doesn't sound like it makes sense...perhaps clever should be an attribute on an Aardvark/Ethel instead ?). That all aside, for a moment. You actually CAN call object.__init__(**kwargs) no problem - as long as kwargs is empty. I'd have written your classes like this: class Aardvark: def __init__(self, quantity, **kwargs): print("There is some quantity:", quantity) # I actually don’t care about **kwargs and just hand them on super().__init__(**kwargs) class Clever: def __init__(self, cleverness=1, **kwargs): print("You are %d clever" % cleverness) super().__init__(**kwargs) class Ethel(Aardvark, Clever): """Ethel is a very clever Aardvark""" def __init__(self, **kwargs): super().__init__(**kwargs) Just try it - it works perfectly fine. Each constructor will consume the keywords meant for it, therefore, the last super() call will call the object constructor without keyword arguments. **kwargs is the price we have to pay for good multiple inheritance - and IMO, it's a low one. If we're talking about signalling what the arguments mean, just ensure you have a good docstring. class Aardvark: def __init__(self, quantity, **kwargs): """ Aardvarks are gentle creatures, and therefore cooperate with multiple inheritance. :param quantity: The quantity of Aardvark(s). """ _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/