how to inherit from typing.NamedTuple and another class correctly?

Viewed 353

There is a class I'm trying to extend, and to save on self.xxx = xxx boilerplate code I'm inheriting a typing.NamedTuple as well. I managed to make it work, but it looks really weird

#!/usr/bin/env python3
from typing import NamedTuple

class FooBar:
    """
    I come from a third-party module, I'm not a particularly nice class.
    I don't welcome or pass through stray arguments,
    neither do I call super().__init__ at all.
    So ideally I have to be inherited first.
    """

    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

    def getFooBar(self):
        return 'foo={}, bar={}'.format(self.foo, self.bar)

BazQux = NamedTuple(
    'BazQux',
    [
        ('baz', 'int'),
        ('qux', 'int')
    ],
);

class Quad(FooBar, BazQux):
    def __new__(cls, **kwargs):
        args4bazqux = {k:v for k, v in kwargs.items() if k not in ('foo', 'bar')}
        # but I'm not calling FooBar.__new__, is that bad?
        return BazQux.__new__(cls, **args4bazqux)

    def __init__(self, **kwargs):
        args4foobar = {k:v for k, v in kwargs.items() if k in ('foo', 'bar')}
        FooBar.__init__(self, **args4foobar)
        # how comes it takes no arguments?
        super(FooBar, self).__init__()

    def getAll(self):
        return '{}, baz={}, qux={}'.format(self.getFooBar(), self.baz, self.qux)

q = Quad(foo=0, bar=1, baz=2, qux=3)
print(q.getAll())

Is it okay to do what I'm doing? Is it portable?

Also, that looks fragile, as it looks like relying on how NamedTuple works. If the other class behaved similarly I wouldn't be able to inherit it as well. Is there a generic solution that would work with any classes, like e.g. with two different NamedTuples?

0 Answers
Related