#python #python-2.7 #inheritance #variadic
#python #python-2.7 #наследование #переменный
Вопрос:
Обрабатываются ли аргументы ключевого слова каким-то образом специально в унаследованных методах?
Когда я вызываю метод экземпляра с аргументами ключевого слова из класса, в котором он определен, все идет хорошо. Когда я вызываю его из подкласса, Python жалуется на слишком много переданных параметров.
Вот пример. «Простые» методы не используют аргументы ключевых слов, и наследование работает нормально (даже для меня 🙂 Методы «KW» используют аргументы ключевых слов, и наследование больше не работает … по крайней мере, я не вижу разницы.
class aClass(object):
def aSimpleMethod(self, show):
print('show: %s' % show)
def aKWMethod(self, **kwargs):
for kw in kwargs:
print('%s: %s' % (kw, kwargs[kw]))
class aSubClass(aClass):
def anotherSimpleMethod(self, show):
self.aSimpleMethod(show)
def anotherKWMethod(self, **kwargs):
self.aKWMethod(kwargs)
aClass().aSimpleMethod('this')
aSubClass().anotherSimpleMethod('that')
aClass().aKWMethod(show='this')
печатает this
, that
, и this
, как я и ожидал. Но
aSubClass().anotherKWMethod(show='that')
бросает:
TypeError: aKWMethod() takes exactly 1 argument (2 given)
Ответ №1:
Когда вы это делаете self.aKWMethod(kwargs)
, вы передаете весь список аргументов ключевого слова в виде одного позиционного аргумента методу (суперкласса) aKWMethod
.
Измените это на self.aKWMethod(**kwargs)
, и оно должно работать так, как ожидалось.
Ответ №2:
Вам нужно использовать ** kwargs при вызове метода, он не принимает позиционных аргументов, только аргументы ключевого слова:
self.aKWMethod(**kwargs)
Как только вы это сделаете, все будет работать нормально:
In [2]: aClass().aSimpleMethod('this')
...: aSubClass().anotherSimpleMethod('that')
...: aClass().aKWMethod(show='this')
...:
show: this
show: that
show: this
Ответ №3:
Просто чтобы продемонстрировать в самых простых терминах, что происходит не так, обратите внимание, что эта ошибка не имеет ничего общего с наследованием. Рассмотрим следующий случай:
>>> def f(**kwargs):
... pass
...
>>> f(a='test') # works fine!
>>> f('test')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 0 positional arguments but 1 was given
Дело в том, что разрешены **kwargs
только аргументы ключевого слова и не могут быть заменены позиционным аргументом.