因此,我有一个大数量的信息的有效载荷的类一个连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)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top