我需要一个类的双重继承。 我尝试了几种语法,但我不理解元类的概念。
from PyQt5.QtGui import QStandardItem
from configparser import ConfigParser
class FinalClass(ConfigParser, QStandardItem):
def __init__(self, param):
ConfigParser.__init__(self)
QStandardItem.__init__(self)
答案 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级等元类,那么您也需要为它们担心。