在Python,我怎么呼叫超级时,它的一namedtuple?
-
28-09-2019 - |
题
因此,我有一个大数量的信息的有效载荷的类一个连API,每一个都有一些不变的领域,一个分析方法,这其中的某些方法是共用的。我现在的结构,这是每个继承从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(whatever)
继承 tuple
, ,这是不可变的,并且不可改变的类型不要打扰 __init__
, 因为时间 __init__
是所谓的对象是已经建造。如果你想通过参数 namedtuple
基类只有复盖 __new__
代替。
你可以看到的定义的结果 namedtuple()
通过在一个 verbose=true
参数;我找到它的教育。
其他提示
你有三个基本类别: Payload
, 你namedtuple DifferentialSpeed_
, 和公共基础类 object
.既不是第一个两个有一个 __init__
功能在所有,除了一个继承了 object
. namedtuple
并不需要一个 __init__
, ,由于初始化的不可改变的类别是通过 __new__
, ,这就是所谓的之前 __init__
运行。
由于 super(DifferentialSpeed, self).__init__
解决下一个 __init__
在呼叫链,下一个 __init__
是 object.__init__
, ,这意味着你通过的参数,功能。它不希望任何--没有任何理由被通过的参数 object.__init__
.
(它使用的接受和默默地忽略的参数。这种行为是要去--它的消失在Python3--这就是为什么你会得到一个DeprecationWarning.)
你可以触发的问题更清楚地加入一个 Payload.__init__
功能需要,没有参数。当你尝试通过沿`*kwargs, 它将提出一个错误。
正确的事情要做,在这种情况下几乎是肯定删除 **kwargs
参数,而只是呼叫 super(DifferentialSpeed, self).__init__()
.它不采取任何论点; DifferentialSpeed
是路过 Payload
它的 自己的 参数 Payload
, 和功能进一步下降的话链、一无所知。
正如其他人已经指出,组是一个不可改变的类型,它必须在其初始化 __new__()
而不是他们 __init__()
方法-所以你需要添加曾在你的亚类(和摆脱后者)。下面是如何将适用于你的代码。唯一其它的变化是加入一个 from import...
发言的开始。
注: cls
必须通过两次 super()
呼叫 __new__()
因为这是一个静态的方法虽然这是特写,所以你不必声明它是一个。
from collections import namedtuple
class Payload:
def test(self):
print("bar")
class DifferentialSpeed(Payload, namedtuple('DifferentialSpeed_',
'left_speed right_speed left_accel right_accel')):
#### NOTE: __new__ instead of an __init__ method ####
def __new__(cls, **kwargs):
self = super(DifferentialSpeed, cls).__new__(cls, **kwargs)
# TODO: Field verification
print("foo")
return self
@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)