Создание подклассов с несколькими конструкторами и ** kwargs

#python #python-3.x #oop #keyword-argument #subclassing

#python #python-3.x #ооп #ключевое слово-аргумент #создание подклассов

Вопрос:

Я пытаюсь создать родительский класс с несколькими конструкторами (используя @classmethod конструктор). В общем, у меня нет проблем с этим, но на этот раз мне нужен __init__ метод для приема произвольных аргументов ключевого слова, поступающих от каждого отдельного конструктора, поэтому я не могу указать их заранее. Затем этот класс несколько раз подразделяется на подклассы по всему коду с использованием различных конструкторов. Проблема в том, что я не могу инициировать родительский класс в подклассах. Я получаю эту ошибку:

 TypeError: __init__() got an unexpected keyword argument 'var1'
 

Это упрощенный пример, который повторяет мою ошибку:

 class Test:
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

    @classmethod
    def from_args(cls, var1):
        return cls(var1=var1)


class SubTest(Test):
    def __init__(self):
        super(SubTest, self).from_args('pie')


if __name__ == '__main__':
    obj = SubTest()
    print(obj.var1)
 

Комментарии:

1.Почему SubTest.__init__ попытка вызова super().from_args ? Он должен, по крайней мере, вызывать либо super().__init__ или self.from_args . Кроме того, поскольку from_args создается новый экземпляр и __init__ инициализируется существующий экземпляр, вызов первого из последнего кажется нецелесообразным.

2. Ну, в таком случае, есть ли какой-либо способ инициализировать super с помощью конструктора from_args (или чего-то подобного)? И это очень упрощенный пример. Очевидно, что я не просто присваиваю var1 в реальной вещи! И в реальном классе есть несколько конструкторов, а не только один. Но вы правы, у меня вылетело из головы, что from_args() создает новый экземпляр, он не инициализирует существующий экземпляр.

3. Я не уверен, что у вас есть правильные инструменты перед вами, если вы хотите SubTest() получить эффект метода classmethod… Возможно, вы могли бы переписать __init__ , чтобы просто вызвать super().__init__(var1='pie') или переопределить classmethod соответствующим образом и использовать SubTest.from_args() .

4. Да, кажется, я искал сложное решение, когда правильный ответ — тот, который дал @MisterMiyagi: простая инициализация, а затем простые, обычные методы класса, которые устанавливают нужные атрибуты (или kwarg в моем случае) в зависимости от случая. Если вы превратите свой комментарий в ответ, я приму его.