Стоит ли использовать super() в Python?

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

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


person Josh Gibson    schedule 11.08.2009    source источник


Ответы (6)


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

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

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

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

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

person e-satis    schedule 11.08.2009
comment
Если функция существует, значит, на то есть причина. Этот аргумент просто не соответствует действительности. Многие языки имеют функции, которые никому и никогда не следует использовать. - person Mike Graham; 28.09.2010

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

person juanjux    schedule 11.08.2009
comment
если вы еще не используете python 3 (что является большинством использования python) - person nosklo; 11.08.2009
comment
Что ты имеешь в виду? super() есть и на Python 2. - person juanjux; 12.08.2009
comment
Я полагаю, это было бэкпортировано. - person ilya n.; 12.08.2009

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

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

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

а также

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

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

person ilya n.    schedule 11.08.2009

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

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

Итак, главный урок заключается в том, что вы должны стараться избегать множественного наследования.

В интересах согласованности я всегда использую супер, даже если для одиночного наследования это не имеет большого значения (кроме небольшого преимущества, заключающегося в том, что не нужно знать имя родительского класса). В Python 3+ super удобнее, так что там обязательно надо использовать super.

person nikow    schedule 11.08.2009

Да, вы должны использовать super() вместо других методов. Теперь это стандартная модель наследования объектов в Python 3.

Просто придерживайтесь ключевых слов в ваших методах __init__, и у вас не должно быть слишком много проблем. Кроме того, вы можете использовать **kwargs для поддержки дополнительных параметров, которые не определены на уровнях цепочки наследования.

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

person cmcginty    schedule 11.08.2009
comment
Вы написали хорошее замечание. Но не могли бы вы сделать свой ответ немного более подробным? Yes на какой вопрос? Название вопроса Is it a good idea to use super() in Python? или первая строка вопроса Or should I just explicitly reference the superclasses whose methods I want to call? . Прочитав ваш ответ несколько раз, я думаю, вы предложили явно ссылаться на суперклассы вместо использования super. Но, на мой взгляд, трудно понять ваш ответ, не прочитав его несколько раз. - person Md. Abu Nafee Ibna Zahid; 19.06.2018
comment
@Md.AbuNafeeIbnaZahid Добавлена ​​дополнительная формулировка. Надеюсь, это поможет. - person cmcginty; 19.06.2018
comment
Спасибо. Сейчас намного лучше. - person Md. Abu Nafee Ibna Zahid; 20.06.2018