Итак, у меня есть большое количество сообщений классов полезной нагрузки для последовательного API, каждый из которых имеет ряд неизменяемых полей, метод анализа и некоторые общие методы. Способ, которым я структурирую это, состоит в том, что каждый из них будет наследовать от namedtuple для поведения полей и получать общие методы из родительского класса. Тем не менее, у меня возникают некоторые трудности с конструкторами:В Python, как я могу назвать суперкласс, когда это одноразовый namedtuple?
class Payload:
def test(self):
print("bar")
class DifferentialSpeed(Payload, namedtuple('DifferentialSpeed_',
'left_speed right_speed left_accel right_accel')):
__slots__ =()
def __init__(self, **kwargs):
super(DifferentialSpeed, self).__init__(**kwargs)
# TODO: Field verification
print("foo")
@classmethod
def parse(self, raw):
# Dummy for now
return self(left_speed = 0.0, right_speed = 0.1,
left_accel = 0.2, right_accel = 0.3)
def __str__(self):
return "Left Speed: %fm/s\nRight Speed: %fm/s\n"\
"Left Acceleration: %fm/s^2\nRight Acceleration: %fm/s^2" % (
self.left_speed, self.right_speed, self.left_accel, self.right_accel)
payload = DifferentialSpeed.parse('dummy')
print(payload)
Это работает, но я получаю следующее предупреждение:
DeprecationWarning: object.__init__() takes no parameters
super(DifferentialSpeed, self).__init__(**kwargs)
Если удалить **kwargs
из разговора, она до сих пор, кажется, работает, но почему? Как эти аргументы для конструктора передаются в namedtuple? Гарантируется ли это, или случайный результат того, как устанавливается mro?
Если бы я хотел держаться подальше от супер, и сделать это по-старому, есть ли способ получить доступ к namedtuple, чтобы вызвать его конструктор? Я бы предпочел не делать этого:
DifferentialSpeed_ = namedtuple('DifferentialSpeed_',
'left_speed right_speed left_accel right_accel')
class DifferentialSpeed(Payload, DifferentialSpeed_):
Кажется, многословный и ненужный.
Каков мой лучший курс действий здесь?
Обратите внимание, что если вы пытаетесь использовать 'namedtuple' для экономии памяти, вам необходимо установить' __slots__ =() 'в производном классе, а также другой унаследованного класса' Payload' или класса все равно будет '__dict__'. –