Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Python, how do I call the super class when it's a one-off namedtuple?

So, I have a large number of message Payload classes for a serial API, each of which has a number of immutable fields, a parse method, and some methods which are shared. The way I'm structuring this is that each will inherit from a namedtuple for the field behaviours, and receive the common methods from a parent class. However, I'm having some difficulties with the constructors:

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)

This works, but I get the following warning:

DeprecationWarning: object.__init__() takes no parameters
  super(DifferentialSpeed, self).__init__(**kwargs)

If I remove **kwargs from the call, it still seems to work, but why? How are those arguments to the constructor getting passed through to the namedtuple? Is this guaranteed, or a random result of how the mro gets established?

If I wanted to stay away from super, and do it the old way, is there some way I can access the namedtuple to call its constructor? I'd rather not have to do this:

DifferentialSpeed_ = namedtuple('DifferentialSpeed_', 
    'left_speed right_speed left_accel right_accel')
class DifferentialSpeed(Payload, DifferentialSpeed_):

Seems kind of verbose and unnecessary.

What's my best course of action here?

like image 778
mikepurvis Avatar asked Nov 01 '10 18:11

mikepurvis


People also ask

Is Namedtuple a class?

NamedTuple . The class created from typing.

Is Super called automatically Python?

__init__() of the superclass ( Square ) will be called automatically. super() returns a delegate object to a parent class, so you call the method you want directly on it: super(). area() . Not only does this save us from having to rewrite the area calculations, but it also allows us to change the internal .

How does super () work Python?

The super() function in Python makes class inheritance more manageable and extensible. The function returns a temporary object that allows reference to a parent class by the keyword super. The super() function has two major use cases: To avoid the usage of the super (parent) class explicitly.

What does super () __ Init__ mean?

The “__init__” is a reserved method in python classes. It is known as a constructor in Object-Oriented terminology. This method when called, allows the class to initialize the attributes of the class. Python super() The super() function allows us to avoid using the base class name explicitly.


1 Answers

For starters, namedtuple(whatever) inherits from tuple, which is immutable, and immutable types don't bother with __init__, because by the time __init__ is called the object is already constructed. If you want to pass arguments to the namedtuple base class you'll have to override __new__ instead.

You can see the definition of the result of namedtuple() by passing in a verbose=true argument; I find it educational.

like image 111
Peter Milley Avatar answered Sep 22 '22 01:09

Peter Milley