Я бы не ожидал каких-либо устойчивых различий в производительности между этими подходами.
Преимущество первого подхода состоит в том, что любой разумно корректный код, на который вы полагаетесь (модули, которые вы импортируете), автоматически выбирает желаемое перенаправление.
Второй подход не имеет преимуществ. Он подходит только для отладки или одноразового кода ... и даже не очень хорошая идея для этого. Вы хотите, чтобы ваши выходные решения были консолидированы в нескольких четко определенных местах, а не разбросаны по всему коду при каждом вызове print()
. В Python3 print()
является функцией, а не оператором. Это позволяет вам переопределить его, если хотите. Так что вы можете def print(*args)
, если хотите. Вы также можете позвонить __builtins__.print()
, если вам нужен доступ к нему, например, в рамках определения вашего собственного пользовательского print()
.
Третий подход ... и, следовательно, принцип, согласно которому все ваши выходные данные должны генерироваться в определенных функциях и методах классов, которые вы определяете для этой цели ..., вероятно, лучше всего.
Вы должны максимально отделить вывод и форматирование от основных функций. Храня их отдельно, вы позволяете вашему ядру быть повторно использованным. (Например, вы можете начать с чего-то, что предназначено для запуска из текстовой консоли или консоли, а затем вам потребуется предоставить веб-интерфейс, полноэкранный интерфейс (curses) или графический интерфейс пользователя. Вы также можете создать совершенно другую функциональность вокруг него ... в ситуациях, когда результирующие данные необходимо возвращать в их исходной форме (как объекты), а не извлекать как текст (вывод) и повторно анализировать в новые объекты.
Например, у меня было несколько случаев, когда что-то, что я писал, выполняло сложные запросы и собирал данные из разных источников и печатал отчет ... скажем о расхождениях ... позже необходимо адаптировать его в форму которые могут выдавать данные в некоторой форме (например, YAML / JSON), которые могут быть переданы в другую систему (скажем, для согласования одного источника данных с другим.
Если с самого начала вы держите основные операции отдельно от вывода и форматирования, тогда этот вид адаптации относительно прост. В противном случае это влечет за собой немало рефакторинга (иногда равносильно полной перезаписи).