Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ABC多重继承_Python_Python 2.7_Multiple Inheritance_Metaclass_Urwid - Fatal编程技术网

Python ABC多重继承

Python ABC多重继承,python,python-2.7,multiple-inheritance,metaclass,urwid,Python,Python 2.7,Multiple Inheritance,Metaclass,Urwid,我认为代码比文字更能解释问题。以下是my_abc.py中的代码: from abc import ABCMeta, abstractmethod class MyABC(object): __metaclass__ = ABCMeta @abstractmethod def print(self): pass 下面是my_class.py中的代码 from my_abc import MyABC from third_party_package im

我认为代码比文字更能解释问题。以下是my_abc.py中的代码:

from abc import ABCMeta, abstractmethod

class MyABC(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def print(self):
        pass
下面是my_class.py中的代码

from my_abc import MyABC
from third_party_package import SomeClass

class MyClass(MyABC, SomeClass):
    def __init__(self):
        super(MyClass, self).__init__()

    def print(self):
        print('Hello ABC')
当我尝试运行我的_class.py时,我得到:

TypeError:调用元类基时出错元类冲突:派生类的元类必须是其所有基的元类的(非严格)子类

我知道我可以创建一个直接从我的接口MyABC继承的类,然后创建另一个类,然后从我创建的这个类和我的第三方模块类继承


我的问题是:有没有另一种更好、更合适的方法可以直接实现这一点,而不必为我的目的创建一个中间类?

SomeClass类有一个自定义元类。您需要创建一个元类,该元类继承自
ABCMeta
和该自定义元类,然后将其用作
MyClass
的元类。如果不了解更多有关此自定义元类的信息,我无法确定在一般情况下执行此操作的正确方法,但它可能看起来像以下几种可能性之一:

class DerivedMeta(ABCMeta, type(SomeClass)):
    pass

class DerivedMeta(type(SomeClass), ABCMeta):
    pass

不太可能,但也可能需要重写一个或多个方法以确保正确的元类交互。

还可以将另一个类的元类设置为ABCMeta,以便所有多个基类的元类都是ABCMeta

使用多重继承时,我遇到了类似的问题:

  • 具有自定义元类的类
  • 以ABCMeta为元类的类
我所做的是使我的自定义元类派生自ABCMeta。这似乎在所有情况下都有效

class MyMeta(ABCMeta):
  pass
这在所有情况下都对我有效

class MyMeta(ABCMeta):
  pass
而不是

class MyMeta(type):
  pass

线程仍然在搜索结果的顶部,所以我想分享我的完整解决方案。
在Python3.8中,我尝试创建一个用于PyQt5小部件的抽象模板类时遇到了这个问题。我应用了@Kevin的解决方案,首先创建了一个新的元类。工作守则:

from abc import ABC, ABCMeta
from PyQt5.QtWidgets import QWidget, QLabel


class QABCMeta(ABCMeta, type(QWidget)):
    """Create a meta class that combines ABC and the Qt meta class"""
    pass


class TcWidget(ABC, metaclass=QABCMeta):
    """Abstract class, to be multi-inherited together with a Qt item"""
    pass


class TcLabel(QLabel, TcWidget):
    """Label that shows a value"""
    pass


# ...
label = TcLabel()
# ...

你建议的变通方法真的有效吗?如果将另一个类放在
MyABC
MyClass
之间,我希望您会遇到完全相同的问题。问题在于
SomeClass
具有不同且不兼容的元类。不知道那是什么,我不确定是否有任何方法可以回答这个问题。你能添加一些关于
SomeClass
的具体细节吗?我正在使用一个名为urwid的第三方库。它是一个ncurses,取代了python,后者有一个更干净的API。根据我上面提供的示例,SomeClass对应于一个urwid.ListBox类,它是一个用于创建类似列表框的UI组件的小部件。我不知道如何找到urwid.ListBox的元类,但是当我使用上面的代码运行它时,我得到了相同的类型错误。尝试创建一个中间元类:
class MyMeta(ABCMeta,type(SomeClass)):pass
,然后将其用作
MyClass
@moeabdol的
元类,但是它也谈到了很多其他的东西。对于那些不知道的人,我在stackoverflow checkout e-satis的回答中找到了一个关于元类的很好的解释谢谢stackoverflow