[PyQt] Issue with multiple inheritance

Dmitry Shachnev mitya57 at ubuntu.com
Sun Jan 22 10:46:45 GMT 2017


Hi Martin!

On Sat, Jan 21, 2017 at 03:26:17PM +0100, Martin Teichmann wrote:
> Hi everybody,
>
> Interestingly, your minimal example works for me. I would still like
> to elaborate a bit on it.
>
> You actual problem is that your inheritance order is wrong. While
> Python supports multiple inheritance, its C backend does not. Because
> of this, you inherit from a Python base class that overrides methods
> from a C base class, but not the other way around, a class written in
> C will call its inherited methods, you cannot override that.
>
> In Python, base classes mentioned first take priority over those
> mentioned last, so given that you can technically (!) only override C
> methods by Python methods, classes implemented in C always go last in
> the inheritance list. (You can only have one of them, so there is no
> doubt).
>
> As an example, take the builtin class dict, which is written in C, and
> another class that overrides, say __getitem__. Such a class is
> traditionally called a Mixin class:
>
>     class Mixin:
>         def __getitem__(self, item):
>               print('trying to get', item)
>               return super().__getitem__(item)
>
>     class MySuperDict(Mixin, dict):
>         pass  # add some cool stuff here
>
> now Mixin.__getitem__ overrides dict.__getitem__ in MySuperDict. Note that
>
>    class MySuperDict(dict, Mixin): # don't do that!
>
> does not work. dict won't even bother about the existence of the Mixin
> base, as it is written in C and doesn't know anything about it, so
> Mixin.__getitem__ will never be called.
>
> So, in short: when programming Python, always put your own Python
> mixin classes first in the inheritance list.
>
> In PyQt, however, Phil didn't like that, because it doesn't look like
> C++ code. Why anyone writing Python would like their code to look like
> C++ I don't know, but apparently there are people out there. So Phil
> went at great length to change the internals of the Python inheritance
> model, only so that you can write
>
>     class MyObject(QObject, Mixin):  # don't do that!
>
> There is, however, no good reason to do so. You can, without any
> problems, simply go with good Python style and write
>
>     class MyObject(Mixin, QObject):
>
> and everything works as expected.
>
> You might now say: but I am not trying to override anything! You are.
> You are trying to override __init__. And for it to work properly, I
> would always recommend to use the super() mechanism, not calling the
> base class directly.
>
> As a side note: the reason things need to be written differently in
> C++ than in Python are because in those languages multiple inheritance
> means something completely different. The overriding in a mixin class
> as described above doesn't exist in C++. On the other hand, C++ has a
> complex system to assure consistent memory layouts in multiple
> inheritance. Python does not support that at all, once you're
> discussing about memory layout, there is not multiple inheritance
> anymore, which eliminates that problem.

You wrote it very well, thanks a lot!

In my own case the problem is already solved, but I am sure that your
response will be helpful for other people like me.

--
Dmitry Shachnev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20170122/60eedfbe/attachment.sig>


More information about the PyQt mailing list