В основном речь идет о Python, но я полагаю, что это, вероятно, относится к большинству языков. Если у меня есть изменяемый объект, то неплохо ли сделать операцию на месте, также вернуть объект? Кажется, что большинство примеров просто изменяют объект и возвращают None
. Например, list.sort
.
Делает ли на месте операции вернуть объект плохую идею?
Ответ 1
Да, это плохая идея. Причина в том, что если операции на месте и без места работы имеют идентичную производительность, то программисты часто будут смешивать операции на месте и операции без места (List.sort()
vs. sorted()
), и результаты в трудно обнаружимых ошибках.
Внутренние операции, возвращаемые сами собой, могут позволить вам выполнить "цепочку методов", однако это плохая практика, потому что вы можете случайно скрыть функции с побочными эффектами в середине цепи.
Чтобы предотвратить такие ошибки, цепи методов должны иметь только один метод с побочными эффектами, и эта функция должна быть в конце цепочки. Функции до этого в цепочке должны преобразовывать вход без побочных эффектов (например, перемещение дерева, нарезка строки и т.д.). Если операции на месте возвращаются, тогда программист обязан случайно использовать его вместо альтернативной функции, которая возвращает копию и поэтому не имеет побочных эффектов (опять же, List.sort()
vs. sorted()
), что может привести к ошибке который трудно отлаживать.
Именно по этой причине стандартные функции библиотеки Python всегда возвращают копию или возвращают None
и изменяют объекты на месте, но никогда не изменяют объекты на месте, а также возвращаются сами. Другие библиотеки Python, такие как Django, также следуют этой практике (см. этот очень похожий вопрос о Django).
Ответ 2
Возврат измененного объекта из модифицированного метода может иметь некоторые преимущества, но не рекомендуется в Python. Возврат self
после операции модификации позволит вам выполнить цепочку методов метода на объекте, что является удобным способом выполнения нескольких методов на одном и том же объекте, это очень общая идиома в объектно-ориентированном программировании. И, в свою очередь, цепочка методов позволяет осуществлять беспрепятственную реализацию плавных интерфейсов. Кроме того, он позволяет легче выражать некоторые идиомы функционального программирования.
Чтобы назвать несколько примеров: в Python библиотека Moka использует цепочку методов. В Java класс StringBuilder
допускает несколько вызовов append()
на одном и том же объекте. В JavaScript JQuery широко использует метод цепочки. Smalltalk переводит эту идею на следующий уровень: по умолчанию все методы возвращают self
, если не указано иное (поэтому поощряют цепочку методов) - сравнивайте это с Python, который по умолчанию возвращает None
.
Использование этой идиомы не является обычным явлением в Python, поскольку Python придерживается принципа Command/Query Separation Principle, в котором говорится, что" каждый метод должен быть либо командой который выполняет действие или запрос, который возвращает данные вызывающему, но не оба.
Все, что считается, хорошая или плохая идея вернуться self
в конце - это вопрос программирования культуры и условности, смешанный с личным вкусом. Как упоминалось выше, некоторые языки программирования поощряют это (например, Smalltalk), тогда как другие препятствуют этому (например, Python). Каждая точка зрения имеет свои преимущества и недостатки, открытые для горячих дискуссий. Если вы являетесь книжным питонистом, лучше воздержитесь от возврата self
- просто помните, что иногда бывает полезно нарушить это правило.
Ответ 3
Я полагаю, это зависит от варианта использования. Я не понимаю, почему было бы больно возвращать объект из-за операции на месте, кроме, может быть, вы не будете использовать результат, но это не проблема, если вы не слишком требовательны к чисто функционализму. Мне нравится шаблон цепочки вызовов, например, использование jQuery, поэтому я ценю его, когда функции возвращают объект, на который они воздействовали, в случае, если я хочу использовать его дальше.