Multiple inheritance metaclass conflict

时光怂恿深爱的人放手 提交于 2019-11-27 19:10:34

问题


I need a double inheritance for a class. I tried several syntaxes but I don't understand the concept of metaclass.

from PyQt5.QtGui import QStandardItem
from configparser import ConfigParser

class FinalClass(ConfigParser, QStandardItem):
    def __init__(self, param):
        ConfigParser.__init__(self)
        QStandardItem.__init__(self)

回答1:


The problem in your case is that the classes you try to inherit from have different metaclasses:

>>> type(QStandardItem)
<class 'sip.wrappertype'> 
>>> type(ConfigParser)
<class 'abc.ABCMeta'>

Therefore python can't decide which should be the metaclass for the newly created class. In this case, it would have to be a class inheriting from both sip.wrappertype (or PyQt5.QtCore.pyqtWrapperType for older PyQt5 versions) and ABCMeta.

Therefore the metaclass conflict could be resolved by explicitly introducing such a class as metaclass like this:

from PyQt5.QtGui import QStandardItem
from configparser import ConfigParser

class FinalMeta(type(QStandardItem), type(ConfigParser)):
    pass

class FinalClass(ConfigParser, QStandardItem, metaclass=FinalMeta):
    def __init__(self, param):
        ConfigParser.__init__(self)
        QStandardItem.__init__(self)

If you want a more detailed description, this article is a good start.

However I'm not really convinced that using multiple inheritance for this situaction is such a good idea, specially using multiple inheritance together with QObjects can be tricky. Maybe it would be better to just store the ConfigParser object as an instance variable and use that when needed.




回答2:


Guido van Rossum often referred to "Putting Metaclasses to Work" book as an inspiration source. PMtW, in return, was written by ex-SOM developers, and was documenting SOM improvements that never happened since being abandoned by IBM.

Guido van Rossum followed PMtW model with regards to cooperative methods and MRO, and thus Python got nice multiple inheritance, which SOM was definitely missing. SOM was more like C++, with explicit parent class calls.

However, he betrayed on of the core ideas of SOM and PMtW with regards to metaclasses. In SOM and PMtW the metaclass is being derived automatically without developer ever bothering if classes have them. It was common to class not actually showing in public: oh, hey, I manage my data with metaclass, but it's my private business. Keep going, nothing important here.

Sometimes the pattern was to explicitly inherit from some class knowing about metaclass behind it. Some metaclasses are placing requirements on classes they manage, and so there is no point to specify metaclass explicitly. You need to derive from designated class anyway, and as soon as you do, you get metaclass as a bonus. Automatically derived metaclasses needed some means to resolve conflicts. And there was methods to implement protocols. These methods could not be introduced by metaclasses, there had to one more layer, rank 3 metaclasses, and canonical Before/After metaclass works like this. 3 is not the limit. The PMtW book has a sample class diagram having 4 layers of metaclasses in their real SOM library, and IMHO all I've seen there makes sense.

It was especially important given that SOM was managing closed source code libraries. It's not a text script to fix in an editor.

Not in Python world, however. Guido van Rossum was too lazy to implement putting.om.Environment.solveMetaclassConstraints from original book. That's why you're facing this issue.

You need to have a headache of bothering of classes' metaclasses in Python. And if they ever get rank 3, rank 4 etc. metaclasses, you need to bother about them too.



来源:https://stackoverflow.com/questions/28720217/multiple-inheritance-metaclass-conflict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!