如何创建从Python中的抽象类继承的抽象类?

2024-10-03 04:39:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我想定义一个从另一个抽象类继承的抽象类。你知道吗

class DataBuffer(ABC):
    def __init__(self):
        self.buffered_data = {}

class IMUDataBuffer(ABC, DataBuffer):
    def __init__(self):
        super(IMUDataBuffer, self).__init__()

    def update(self, message):
        timestamp = message['ts']
        x_val, y_val, z_val = message[self.message_key]
        self.buffered_data[timestamp] = (x_val, y_val, z_val)

class GyroscopeDataBuffer(IMUDataBuffer):
    def __init__(self):
        super(GyroscopeDataBuffer, self).__init__()
        self.message_key = 'gy'

class AccelerometerDataBuffer(IMUDataBuffer):
    def __init__(self, message):
        super(AccelerometerDataBuffer, self).__init__()
        self.message_key = 'ac'

在本例中,IMUDataBuffer应该从DataBuffer继承方法,但它本身永远不会被实例化,因此应该是一个抽象类。你知道吗

这是我收到的上面代码的错误:

TypeError: Cannot create a consistent method resolution order (MRO) for bases ABC, DataBuffer

作为一种廉价的解决方法,我可以在IMUDatabuffer中定义一个message\u键,但这让我觉得有些草率,因为IMUDatabuffer实际上不应该有message\u键属性。你知道吗

class IMUDataBuffer(DataBuffer):
    def __init__(self):
        super(IMUDataBuffer, self).__init__()
        self.message_key = None

在这里处理继承的正确方法是什么?你知道吗


Tags: 方法keyselfmessage定义initdef抽象类
3条回答

在Python中,简单地从ABC继承并不能阻止实例化。这很好:

from abc import ABC

class Foo(ABC):
    pass

foo = Foo()

只有在存在未实现的abstractmethod时,实例化才会引发错误

您的中间类不必从ABC继承,只需从DataBuffer继承即可。只要有未实现的abstractmethod的实例化就会失败。你知道吗

from abc import ABC, abstractmethod

class Foo(ABC):
    @abstractmethod
    def do_thing(self):
        pass

class Bar(Foo):
    pass

bar = Bar()  # Instantiation raises TypeError because Bar does not implement do_thing

由于Bar继承自Foo,Foo是一个抽象类,因此Bar也是一个抽象类:

>>> type(Foo)
<class 'abc.ABCMeta'>
>>> type(Bar)
<class 'abc.ABCMeta'>

与其他随机类比较:

>>> class Baz:
>>>    pass
>>> type(Baz)
<class 'type'>

这是菲克斯-

from abc import *

class DataBuffer(ABC):
    def __init__(self):
        self.buffered_data = {}

class IMUDataBuffer(DataBuffer, ABC):
    def __init__(self):
        super(IMUDataBuffer, self).__init__()

    def update(self, message):
        timestamp = message['ts']
        x_val, y_val, z_val = message[self.message_key]
        self.buffered_data[timestamp] = (x_val, y_val, z_val)

有关详细说明,请参阅此- Why is this an ambiguous MRO?

我建议删除IMUDataBuffer父列表中的ABC,因为DataBuffer已经有ABC作为父。你知道吗

ABC -> DataBuffer -> IMUDataBuffer -> Gyroscope
                                   -> Accelerometer

代码如下所示:

class ABC:
    pass

class DataBuffer(ABC):  # <  brings already all stuff from ABC
    def __init__(self):
        self.buffered_data = {}

class IMUDataBuffer(DataBuffer):  # <  ABC removed here
    def __init__(self):
        super(IMUDataBuffer, self).__init__()

    [...]

然后错误消失。你知道吗

相关问题 更多 >