多继承元类冲突

时间:2015-02-25 13:26:33

标签: python-3.x pyqt multiple-inheritance

我需要一个类的双重继承。 我尝试了几种语法,但我不理解元类的概念。

from PyQt5.QtGui import QStandardItem
from configparser import ConfigParser

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

2 个答案:

答案 0 :(得分:14)

您的案例中的问题是您尝试继承的类具有不同的元类:

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

因此,python不能决定哪个应该是新创建的类的元类。在这种情况下,它必须是继承自sip.wrappertype(或旧版PyQt5版本的PyQt5.QtCore.pyqtWrapperType)和ABCMeta的类。

因此,元类冲突可以通过明确地引入类如下的元类来解决:

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)

如果您想要更详细的说明,this article是一个良好的开端。

然而,我并不是真的相信在这种情境中使用多重继承是一个好主意,特别是将多重继承与QObjects一起使用可能会非常棘手。也许最好只将ConfigParser对象存储为实例变量,并在需要时使用它。

答案 1 :(得分:-2)

Guido van Rossum经常将“将元类投入工作”一书作为灵感来源。作为回报,PMtW由前SOM开发人员编写,并记录了自从IBM放弃以来从未发生过的SOM改进。

Guido van Rossum在合作方法和MRO方面遵循了PMtW模型,因此Python获得了很好的多重继承,而SOM无疑是缺失的。 SOM更像是C ++,具有显式的父类调用。

但是,他背叛了SOM和PMtW关于元类的核心思想。在SOM和PMtW中,元类是自动派生的,开发人员无需费心去拥有类。上课实际上没有公开显示是很常见的:哦,嘿,我使用元类管理数据,但这是我的私人业务。继续前进,这里没什么重要的。

有时,模式是从知道有关其背后的元类的某个类显式继承的。一些元类对他们管理的类提出了要求,因此没有必要明确指定元类。无论如何,您都需要从指定的类派生,而一旦这样做,您就会获得元类作为奖励。自动派生的元类需要一些方法来解决冲突。并且有实现协议的方法。这些方法无法由元类引入,必须再一层,对3个元类进行排名,并且规范的元类之前/之后像这样工作。 3不是极限。 PMtW书中有一个示例类图,它们的真实SOM库中包含4层元类,而恕我直言,我在那看到的一切都是有道理的。

鉴于SOM正在管理封闭的源代码库,这一点尤其重要。这不是要在编辑器中修复的文本脚本。

但是,在Python世界中不是。吉多·范·罗苏姆(Guido van Rossum)懒得执行原书中的putting.om.Environment.solveMetaclassConstraints。这就是您面对此问题的原因。

您需要为Python中的类的元类困扰。而且,如果它们曾经获得过3级,4级等元类,那么您也需要为它们担心。