Это хорошая идея использовать 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__
, и у вас не должно быть слишком много проблем.
Я согласен, что он хрупкий, но не менее, чем использование имени унаследованного класса.