как правильно наследовать от typing.NamedTuple и другого класса? - PullRequest
1 голос
/ 24 октября 2019

Есть класс, который я пытаюсь расширить, и чтобы сэкономить на self.xxx = xxx шаблонном коде, я также наследую typing.NamedTuple. Мне удалось заставить это работать, но это выглядит действительно странно

#!/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())

Можно ли делать то, что я делаю? Это портативное устройство?

Кроме того, это выглядит хрупким, так как похоже на то, как работает NamedTuple. Если бы другой класс вел себя аналогично, я бы тоже не смог его унаследовать. Есть ли общее решение, которое будет работать с любыми классами, например, с двумя разными NamedTuple s?

...