#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 в моем случае) в зависимости от случая. Если вы превратите свой комментарий в ответ, я приму его.