Разница между sys.stdout.write и print? - PullRequest
321 голосов
/ 16 июля 2010

Существуют ли ситуации, в которых sys.stdout.write() предпочтительнее, чем print?

( Примеры: лучшая производительность; более понятный код)

Ответы [ 11 ]

257 голосов
/ 16 июля 2010

print - это просто тонкая оболочка, которая форматирует входные данные (изменяемые, но по умолчанию с пробелом между аргументами и символом новой строки в конце) и вызывает функцию записи данного объекта. По умолчанию этот объект sys.stdout, но вы можете передать файл, используя форму "шеврон". Например:

print >> open('file.txt', 'w'), 'Hello', 'World', 2+3

См .: https://docs.python.org/2/reference/simple_stmts.html?highlight=print#the-print-statement


В Python 3.x print становится функцией, но все еще возможно передать что-то отличное от sys.stdout благодаря аргументу file.

print('Hello', 'World', 2+3, file=open('file.txt', 'w'))

См. https://docs.python.org/3/library/functions.html#print


В Python 2.6+, print все еще является оператором, но его можно использовать как функцию с

from __future__ import print_function

Обновление: Бакуриу прокомментировал, что указал на небольшую разницу между функцией печати и оператором печати (и, в более общем смысле, между функцией и оператором).

В случае ошибки при оценке аргументов:

print "something", 1/0, "other" #prints only something because 1/0 raise an Exception

print("something", 1/0, "other") #doesn't print anything. The function is not called
134 голосов
/ 16 июля 2010

print сначала преобразует объект в строку (если это еще не строка). Он также ставит пробел перед объектом, если это не начало строки и символ новой строки в конце.

При использовании stdout вам необходимо самостоятельно преобразовать объект в строку (например, вызвав "str"), а символ перевода строки отсутствует.

So

print 99

эквивалентно:

import sys
sys.stdout.write(str(99) + '\n')
37 голосов
/ 16 июля 2010

Мой вопрос: есть или нет ситуации, в которых sys.stdout.write() предпочтительнее print

Закончив разработку скрипта на днях, я загрузил его на сервер Unix. Все мои сообщения отладки использовали операторы print, и эти не появляются в журнале сервера.

Это тот случай, когда вам может понадобиться sys.stdout.write.

35 голосов
/ 29 августа 2012

Вот пример кода, основанного на книге Марка Лутца Learning Python , которая отвечает на ваш вопрос:

import sys
temp = sys.stdout                 # store original stdout object for later
sys.stdout = open('log.txt', 'w') # redirect all prints to this log file
print("testing123")               # nothing appears at interactive prompt
print("another line")             # again nothing appears. it's written to log file instead
sys.stdout.close()                # ordinary file object
sys.stdout = temp                 # restore print commands to interactive prompt
print("back to normal")           # this shows up in the interactive prompt

Открытие log.txt в текстовом редакторе покажет следующее:

testing123
another line
11 голосов
/ 31 августа 2016

Существует по крайней мере одна ситуация, в которой вы хотите sys.stdout вместо печати. ​​

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

Note carriage return-> "\rMy Status Message: %s" % progress

. И так как print добавляет новую строку, вам лучше использовать sys.stdout.

8 голосов
/ 08 июля 2013

У меня вопрос, есть ли ситуации, в которых sys.stdout.write() предпочтительнее print

Если вы пишете приложение командной строки, которое может записывать как в файлы, так и в stdout, то это удобно. Вы можете делать такие вещи, как:

def myfunc(outfile=None):
    if outfile is None:
        out = sys.stdout
    else:
        out = open(outfile, 'w')
    try:
        # do some stuff
        out.write(mytext + '\n')
        # ...
    finally:
        if outfile is not None:
            out.close()

Это означает, что вы не можете использовать шаблон with open(outfile, 'w') as out:, но иногда оно того стоит.

3 голосов
/ 16 июля 2010

В 2.x оператор print предварительно обрабатывает то, что вы ему даете, превращая его в строки по ходу, обрабатывая разделители и символы новой строки и разрешая перенаправление в файл. 3.x превращает его в функцию, но все равно выполняет те же обязанности.

sys.stdout - это файл или файл, в котором есть методы для записи в него, которые принимают строки или что-то подобное.

1 голос
/ 26 октября 2018

предпочтительно, когда динамическая печать полезна, например, для предоставления информации в длительном процессе:

import time, sys
Iterations = 555
for k in range(Iterations+1):
    # some code to execute here ...
    percentage = k / Iterations
    time_msg = "\rRunning Progress at {0:.2%} ".format(percentage)
    sys.stdout.write(time_msg)
    sys.stdout.flush()
    time.sleep(0.01)
1 голос
/ 25 октября 2018

В Python 3 есть веская причина использовать print over sys.stdout.write, но эту причину также можно превратить в причину использования sys.stdout.write.

Эта причина в том, что теперь printФункция в Python 3, вы можете переопределить это.Таким образом, вы можете использовать print везде в простом сценарии и решить, что эти операторы печати должны записывать в stderr.Теперь вы можете просто переопределить функцию печати, вы даже можете изменить глобальную функцию печати, изменив ее с помощью встроенного модуля.Конечно, с помощью file.write вы можете указать, что это за файл, но при перезаписи печати вы также можете переопределить разделитель строк или разделитель аргументов.

И наоборот.Возможно, вы абсолютно уверены, что пишете в stdout, но также знаете, что собираетесь изменить печать на что-то другое, вы можете решить использовать sys.stdout.write и использовать печать для журнала ошибок или чего-то еще.

Итак, то, что вы используете, зависит от того, как вы собираетесь его использовать.print более гибок, но это может быть причиной, чтобы использовать и не использовать его.Я бы все равно выбрал гибкость и выбрал печать.Еще одна причина использовать print вместо этого - фамильярность.Больше людей теперь поймут, что вы подразумеваете под печатью, и меньше узнают sys.stdout.write.

1 голос
/ 04 сентября 2018

Существуют ли ситуации, в которых sys.stdout.write () предпочтительнее печатать?

Я обнаружил, что стандартный вывод работает лучше, чем печать в многопоточном режиме.Я использую очередь (FIFO), чтобы сохранить строки для печати, и держу все нити перед строкой печати, пока моя печать Q не станет пустой.Тем не менее, при использовании print я иногда теряю последний \ n при отладочном вводе / выводе (используя wing pro IDE).

Когда я использую std.out с \ n в строке, форматирование отладочного ввода / вывода корректнои \ n точно отображаются.

...