Функция 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)

person virtualnobi    schedule 12.10.2016    source источник


Ответы (3)


Когда вы выполняете self.aKWMethod(kwargs), вы передаете весь набор аргументов ключевого слова как один позиционный аргумент методу (суперкласса) aKWMethod.

Измените это на self.aKWMethod(**kwargs), и оно должно работать как положено.

person Tom Dalton    schedule 12.10.2016

Вам нужно использовать **kwargs при вызове метода, он не принимает позиционные аргументы, только аргументы ключевого слова:

 self.aKWMethod(**kwargs)

Как только вы это сделаете, он отлично работает:

In [2]: aClass().aSimpleMethod('this')
   ...: aSubClass().anotherSimpleMethod('that')
   ...: aClass().aKWMethod(show='this')
   ...: 
show: this
show: that
show: this
person Padraic Cunningham    schedule 12.10.2016

Просто чтобы продемонстрировать в самых простых терминах, что происходит не так, обратите внимание, что эта ошибка не имеет ничего общего с наследованием. Рассмотрим следующий случай:

>>> 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 только допускает аргументы ключевого слова и не может быть заменен позиционным аргументом.

person brianpck    schedule 12.10.2016