Это хорошая идея использовать super() в Python?

Или я просто должен явно ссылаться на суперклассы, методы которых я хочу вызвать?

Кажется хрупким повторять имена суперклассов при ссылках на их конструкторы, но эта страница http://fuhm.net/super-harmful/ дает хорошие аргументы против использования супер().

Ответ 1

В книге Expert Python Programming обсуждалась тема "супер ловушек" в главе 3. Это стоит прочитать. Ниже приведен книжный вывод:

Использование Super должно быть последовательным: в иерархии классов супер следует использовать везде или нигде. Смешивание супер-и классических вызовов - это запутанная практика. Люди склонны избегать супер, потому что их код будет более явным.

Изменить: Сегодня я снова прочитал эту часть книги. Я скопирую еще несколько предложений, так как супер-использование сложно:

  • Избегайте множественного наследования в вашем коде.
  • Будьте в согласии с его использованием и не смешивайте новый стиль и старый стиль.
  • Проверяйте иерархию классов перед вызовом своих методов в ваш подкласс.

Ответ 2

Вы можете использовать супер, но, как говорится в статье, есть недостатки. Пока вы их знаете, нет проблем с использованием этой функции. Это похоже на то, что люди говорят "использовать состав, а не наследование" или "никогда не использовать глобальные переменные". Если функция существует, есть причина. Просто не забудьте понять, почему, и что и использовать их с умом.

Ответ 3

Проблема, с которой люди сталкиваются с super, скорее, является проблемой множественного наследования. Так что это немного несправедливо обвинять super. Без super множественное наследование еще хуже. Michele Simionato красиво завернул это в своей статье

Ответ 4

Мне нравится super() больше, потому что он позволяет вам изменить унаследованный класс (например, при рефакторинге и добавлении промежуточного класса), не меняя его на все методы.

Ответ 5

super() пытается решить для вас проблему множественного наследования; трудно воспроизвести его семантику, и вы, конечно же, не должны создавать новую семантику, если не будете полностью уверены.

Для одиночного наследования нет никакой разницы между

class X(Y):
    def func(self):
        Y.func(self)

и

class X(Y):
    def func(self):
        super().func()

поэтому я думаю, что только вопрос вкуса.

Ответ 6

Да, просто придерживайтесь аргументов ключевого слова в своих методах __init__, и у вас не должно быть слишком много проблем.

Я согласен, что он хрупкий, но не менее, чем использование имени унаследованного класса.