pythonclassinheritancedronekit-pythondronekit

Creating a subclass without direct access to the parent class __init__() function


I'm using the DroneKit API in Python for controlling a drone using a companion computer. I'm trying to create a class, Vehicle, which inherits from the Vehicle class in DroneKit. The purpose of this class is for me to override some methods present in DroneKit that don't work with PX4 as well as adding a few methods of my own, whilst still having access to all of the methods available by default.

The issue is that you don't create a Vehicle object directly using Dronekit – you call the connect() function which return a Vehicle object.

My question is, how do I create an instance of my class?

The accepted method seems to be to call the parent init(), like so:

class Vehicle(dronekit_Vehicle):
    def __init__(self, stuff):
        dronekit_Vehicle.__init__(stuff)

But like I said, you don't create a Vehicle object directly in Dronekit, e.g. vehicle = Vehicle(stuff), but by vehicle = connect(stuff), which eventually returns a Vehicle object but also does a bunch of other stuff.

The only way I can think of is

class Vehicle(dronekit_Vehicle):
    def __init__(self, stuff):
        self.vehicle = connect(stuff)

And then having to use self.vehicle.function() to access the default DroneKit commands and attributes, which is a huge pain.

How do I make this work?


Solution

  • The way objects are defined has nothing to do with connect. Calling connect is merely some convenience function that wraps some logic around the object creation:

    def connect(...):
        handler = MAVConnection(...)
        return Vehicle(handler)
    

    with Vehicle.__init__() being defined as

    def __init__(self, handler):
        super(Vehicle, self).__init__()
        self._handler = handler
        ...
    

    So as long as you pass on the handler in your constructor:

    class MyVehicle(dronekit.Vehicle):
        def __init__(self, handler):
          super(MyVehicle, self).__init__(handler)
    

    Your class will work with connect():

    connect(..., vehicle_class=MyVehicle)