Подтвердить что ты не робот

Super() и @staticmethod

Не используется ли super() для использования со статическими методами?

Когда я пытаюсь что-то вроде

class First(object):
  @staticmethod
  def getlist():
    return ['first']

class Second(First):
  @staticmethod
  def getlist():
    l = super(Second).getlist()
    l.append('second')
    return l

a = Second.getlist()
print a

Я получаю следующую ошибку

Traceback (most recent call last):
  File "asdf.py", line 13, in <module>
    a = Second.getlist()
  File "asdf.py", line 9, in getlist
    l = super(Second).getlist()
AttributeError: 'super' object has no attribute 'getlist'

Если я изменю staticmethods на classmethods и передаю экземпляр класса super(), все будет работать нормально. Я называю super (type) неправильно здесь или есть что-то, чего я не хватает?

4b9b3361

Ответ 1

Короткий ответ

Я называю super (type) неправильно здесь или есть что-то, чего я не хватает?

: да, вы неправильно его называете... И (действительно, потому что) есть что-то, чего вам не хватает.

Но не чувствую себя плохо; это чрезвычайно трудный вопрос.

В документации отмечается, что

Если второй аргумент опущен, возвращаемый супер объект не связан.

Вариант использования для несвязанных объектов super чрезвычайно узкий и редок. См. Эти статьи Микеле Симионато для обсуждения super():

Кроме того, он настоятельно рекомендует удалить unbound super из Python 3 здесь.

Я сказал, что вы называете это "неправильно" (хотя правильность в значительной степени бессмысленна без контекста, а пример игрушки не дает большого контекста). Поскольку unbound super настолько редок и, возможно, просто не обоснован, как утверждает Simionato, "правильный" способ использования super() состоит в том, чтобы предоставить второй аргумент.

В вашем случае самый простой способ сделать ваш пример работы -

class First(object):
  @staticmethod
  def getlist():
    return ['first']

class Second(First):
  @staticmethod
  def getlist():
    l = super(Second, Second).getlist()  # note the 2nd argument
    l.append('second')
    return l

a = Second.getlist()
print a

Если вы думаете, что это выглядит смешно, вы не ошибаетесь. Но я думаю, что большинство людей ожидает, когда они видят super(X) (или надеясь, когда они попробуют это в своем собственном коде), это то, что дает Python, если вы делаете super(X, X).

Ответ 2

Когда вы вызываете обычный метод для экземпляра объекта, метод получает экземпляр объекта как первый параметр. Он может получить класс hte-объекта и его родительский класс, поэтому имеет смысл вызвать super.

Когда вы вызываете метод classmethod для экземпляра объекта или класса, метод получает этот класс как первый параметр. Он может получить родительский класс, поэтому имеет смысл вызвать super.

Но когда вы вызываете метод staticmethod, метод ничего не получает, у него нет способа узнать, из какого объекта или класса он был вызван. Это причина, по которой вы не можете получить доступ к super в staticmethod.