[Python-ideas] Is multiple inheritance Pythonic?

Mahmoud Hashemi mahmoud at hatnote.com
Fri Mar 18 14:47:22 EDT 2016


Discerning use of multiple inheritance is very Pythonic. Look no further
than Exception use cases:

class PathAccessError(KeyError, IndexError, TypeError):
<https://github.com/mahmoud/boltons/blob/master/boltons/iterutils.py#L880>

It might look a little wonky at first, but when you understand the use
case, you'll see the utility. There are loads of these sorts of use cases
sprinkled throughout the community, in some of the most Pythonic libraries
around.

Mahmoud

On Fri, Mar 18, 2016 at 11:11 AM, Martin Teichmann <lkb.teichmann at gmail.com>
wrote:

> Hi List,
>
>
> Summary: Multiple inheritance is not used in new code of the standard
> library anymore, even where it could be of good use. Should multiple
> inheritance thus be abandoned, or supported more?
>
>
> I am currently developing a little library for the communication in our
> project. It is supposed to support different protocols, encryptions and
> addressing standards.
>
> At first I thought I'd just use multiple inheritance. A user of the library
> would then just write a little stub-class, as in:
>
>     class MyProtocol(URLAdressMixin, SSLEncryptionMixin, HTTPProtocol):
>         pass
>
> and voilà! everything is ready.
>
> But because I try to be one of the cool guys, I tried to do all of that
> using
> asyncio. It has a pluggable event loop, where you can plug in your own
> event loop with the specifics of your project. Again, I thought, let's
> to multiple
> inheritance! I needed some priority scheduling, so just write a mixin that
> does
> that, and mix it into the base class of the event loop.
>
> To my astonishment, the designers of asyncio explicitly decided against
> that
> option. They prefer not to let users subclass at all. Instead, asyncio has
> a factory plugin system, as an example, one can call set_task_factory
> to modify what the BaseEventLoop.create_task method is doing. Things
> like that used to be clearly the domain of mixin classes.
>
> The question arised, why would one do that? Is multiple inheritance bad,
> or not Pythonic?
>
> Guessing what the decisions of the asyncio developers were, several
> problems
> come to my mind. Firstly, metaclasses a notoriously problematic in a
> multiple
> inheritance context. Some of you might have seen my work on PEP 487 to
> mitigate that problem.
>
> Another issue are the stub classes mentioned above.
> One ends up writing lots of little stub classes combining mixins
> together. (An example from
> https://github.com/jupyter/qtconsole/blob/master/qtconsole/inprocess.py:
> class QtInProcessKernelManager(QtKernelManagerMixin,
> InProcessKernelManager):)
> Many users don't like that, it's too much programming, too little using.
>
> Another problem is that mixins cannot be mixed-in at runtime anymore.
> Once the event loop is running, I cannot sneak in a new task factory
> anymore.
> It is questionable whether that's desired. Another argument is that
> using the factory way, a library might "sneak in" its factories without the
> user noticing. But in my opinion, that's against the Pythonic concept of
> being explicit. A library should rather document: "Hey, you need to include
> SuperTaskMixin into your Eventloop", rather than silently setting a new
> factory.
>
> This also touches mainainability a lot. Imagine you are using two
> libraries,
> both at some time deciding they need to set a task factory. That won't work
> out.
>
> All of this is nicely solved in a multiple inheritance scheme: the
> method resolution
> order using super() is flexible enough to allow two independent extensions
> of
> create_task, as long as it is properly documented how to use it.
>
> So both concepts, multiple inheritance as well as pluggable factories, have
> their pros and cons. According to the Zen, there should ideally only be
> one way of doing things, but given that I'm not Dutch I just don't see what
> that way is. Please help me out.
>
> In my opinion, either
>
> a) multiple inheritance should be declared not Pythonic and frowned upon,
> or
> b) made easy to use and well supported
>
> In case of a), it would be nice to have proper facilities set up to have a
> good
> factory plugin mechanism (for example one that also allows to put in
> several plugins)
>
> Or in the b) case, it should be easier to use multiple inheritance and
> mixins. I was thinking about a class algebra, so following the above
> example one could create a mixed class simply as
> MyProtocol = SSLMixin + HTTPProtocol. This would lead do options
> (going back to asyncio) like
>
> asyncio.set_event_loop((PriorityMixin + QtEventLoop)())
>
> What do you all think about that?
>
> Greetings
>
> Martin
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160318/9ce7047d/attachment-0001.html>


More information about the Python-ideas mailing list