如何创建从 Python 中的抽象 class 继承的抽象 class?
How can I create an abstract class that inherits from an abstract class in Python?
我想定义一个抽象 class,它继承自另一个抽象 class。
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 的方法,但它本身永远不会被实例化,因此应该是一个抽象 class。
这是我在上面的代码中收到的错误:
TypeError: Cannot create a consistent method resolution order (MRO) for bases ABC, DataBuffer
作为一种廉价的解决方法,我可以在 IMUDatabuffer 中定义一个 message_key,但这对我来说感觉很草率,因为 IMUDataBuffer 实际上不应该有一个 message_key 属性 .
class IMUDataBuffer(DataBuffer):
def __init__(self):
super(IMUDataBuffer, self).__init__()
self.message_key = None
此处处理继承的正确方法是什么?
我建议删除 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__()
[...]
然后错误消失。
这是修复 -
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)
另请参阅此以获取详细说明 -
在 Python 中,简单地从 ABC 继承并不会阻止实例化。这很好用:
from abc import ABC
class Foo(ABC):
pass
foo = Foo()
如果有未实现的abstractmethod
,实例化只会引发错误。
你的中间 class 不必从 ABC 继承,只需从 DataBuffer
继承。只要有未实现的 abstractmethod
s 实例化就会失败。
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是一个抽象class,Bar也是一个抽象class:
>>> type(Foo)
<class 'abc.ABCMeta'>
>>> type(Bar)
<class 'abc.ABCMeta'>
与其他一些随机比较class:
>>> class Baz:
>>> pass
>>> type(Baz)
<class 'type'>
我想定义一个抽象 class,它继承自另一个抽象 class。
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 的方法,但它本身永远不会被实例化,因此应该是一个抽象 class。
这是我在上面的代码中收到的错误:
TypeError: Cannot create a consistent method resolution order (MRO) for bases ABC, DataBuffer
作为一种廉价的解决方法,我可以在 IMUDatabuffer 中定义一个 message_key,但这对我来说感觉很草率,因为 IMUDataBuffer 实际上不应该有一个 message_key 属性 .
class IMUDataBuffer(DataBuffer):
def __init__(self):
super(IMUDataBuffer, self).__init__()
self.message_key = None
此处处理继承的正确方法是什么?
我建议删除 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__()
[...]
然后错误消失。
这是修复 -
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)
另请参阅此以获取详细说明 -
在 Python 中,简单地从 ABC 继承并不会阻止实例化。这很好用:
from abc import ABC
class Foo(ABC):
pass
foo = Foo()
如果有未实现的abstractmethod
,实例化只会引发错误。
你的中间 class 不必从 ABC 继承,只需从 DataBuffer
继承。只要有未实现的 abstractmethod
s 实例化就会失败。
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是一个抽象class,Bar也是一个抽象class:
>>> type(Foo)
<class 'abc.ABCMeta'>
>>> type(Bar)
<class 'abc.ABCMeta'>
与其他一些随机比较class:
>>> class Baz:
>>> pass
>>> type(Baz)
<class 'type'>