Для математиков операторы важны для мышления.Возьмём простую операцию, например, сложение двух чисел, и попробуем разобраться в её поведении.
add (x, y) == add (y, x) (1)
Уравнение (1) выражает закон коммутативности сложения.Обычно его записывают с использованием оператора, что делает запись более краткой:
x + y == y + x (1a)
Кажется, это небольшое преимущество.Теперь рассмотрим ассоциативный закон:
add (x, add (y, z)) == add (add (x, y), z) (2)
Уравнение (2) можно переписать с использованием операторов:
x + (y + z) == (x + y ) + z (2a)
Это гораздо менее запутанно, чем (2), и приводит к наблюдению, что скобки излишни, поэтому теперь мы можем записать
x + y + z (3)
Многие другие законы также проще записать с использованием операторов.Вот ещё один пример с элементом идентификации сложения:
add (x, 0) == add (0, x) == x (4)
сравните с этой записью:
x + 0 == 0 + x == x (4a)
Главная идея здесь заключается в том, что после изучения этой простой записи уравнения, записанные с её помощью, будут легче «манипулировать», чем уравнения, записанные с помощью функциональной записи.
Пожалуй, все согласятся с утверждением, что формулы, записанные с помощью операторов, лучше понятны.Этот процесс происходит подсознательно, но благодаря ему мы понимаем, что видим на самом деле. Например, «стул», а не «деревянные доски, соединённые определённым образом».Запись в виде функций привлекает другие части нашего мозга, менее подсознательные (это связано с чтением и пониманием прочитанного).
Сила визуального восприятия становится очевидной при использовании нескольких операторов.Рассмотрим дистрибутивный закон:
mul(n, add(x, y)) == add(mul(n, x), mul(n, y)) (5).
Написать это было мучительно.К тому же, большинство читателей даже не сразу поймут, что это тот же дистрибутивный закон.
Сравним это с такой записью:
n(x + y) == nx + ny (5b)
но, к сожалению, в настоящее время это выходит за рамки возможностей парсера Python.
Ещё одним очень важным аспектом операторной нотации является то, что её можно удобно применять к различным типам объектов.Например, законы (1)–(5) работают также, когда x, y и z — векторы одинакового размера, а n — скаляр (заменяя вектор нулей на литерал «0»), а также если это матрицы (опять же, n должно быть скаляром).
И это можно делать с объектами из разных областей определения. Например, вышеупомянутые законы (1)–(5) применяются к функциям (n — снова скаляр).
При выборе операторов математики используют своё визуальное восприятие в качестве помощника: так они быстрее открывают новые законы.
Программирование отличается от математики. Но все мы знаем, что читаемость важна, и именно здесь вступает в игру перегрузка операторов в Python.Как только вы освоите простые свойства операторов, вы поймёте, что + для конкатенации строк или списков выглядит более читабельно, и выше мы уже частично объяснили, почему это так.
Конечно, можно переусердствовать — тогда получится Perl.Но мы часто забываем, что следующую запись гораздо проще понять:
d = d1 + d2
по сравнению с этой:
d = d1.copy ( ) d.update (d2)
и дело не только в меньшем количестве строк кода: первая форма позволяет нам использовать визуальную обработку, чтобы быстрее увидеть смысл — и не отвлекать другие части нашего мозга (которые, возможно, уже заняты отслеживанием значения d1 и d2, например).
Конечно, за всё приходится платить.Необходимо изучать операторы и их свойства применительно к различным типам объектов.(Это справедливо и в математике — для чисел справедливо x * y == y * x, но это свойство неприменимо к функциям или матрицам, с другой стороны, x + y == y + x (закон ассоциативности) выполняется для всех типов.)
Многих беспокоит вопрос производительности.Я считаю, что сначала важна читаемость, а потом — производительность.Если вернуться к примеру с d = d1 + d2, мы не увидим потери производительности по сравнению с версией без операторов. Кроме того, достигается значительное преимущество в читаемости.Видно, что в большинстве случаев разница в производительности не настолько велика, чтобы жертвовать читаемостью.В тех случаях, когда производительность выходит на первый план, можно легко заменить версию с операторами на другую (например, с помощью профилирования).