2014-12-05 3 views
4

В то время как я пытался несколько питания в моем Python 3 интерпретатора (Python 3.4.2, установленного через варку), я столкнулся с некоторыми странные выходы я не ожидалось:Странное поведение в Python 3 с помощью модуля Sys

>>> import sys 
>>> sys.stdout.write("foo") 
foo3 
>>> sys.stderr.write("bar") 
3 
bar 

После экспериментирования с разными строками, я думаю, что число - это длина входов, которые я передаю.

Я попытался это в Python 2.7.8 (не дает номера в выходах) и Python 3.4.2, созданные virtualenv (дает тот же результат)

должен ли выход быть, как это?

+1

Я считаю, что это ожидаемое поведение. Число печатается только потому, что вы находитесь в python REPL. Не будет никаких чисел, если вы запустите этот код как скрипт. – zaquest

ответ

5

Вы правы, что это длина. В Python 2 возвращается метод File.write()None. Когда переход был сделан на Python 3, возвращаемое значение изменилось на количество написанных символов.

Причина, по которой вы получаете разные выходные данные от stdout и stderr, вероятно, связана с порядком, в котором все отображается на дескрипторах файла.

Для stdout, write выходы "foo", тогда цикл REPL (в традициях PIN-номеров и банкоматов) выводит счет в тот же поток.

Для stderr вполне вероятно, что цикл REPL выдает стандартный вывод сначала (длина), а затем содержимое стандартной ошибки.

Или это может быть совершенно недетерминированным, это, вероятно, не то, на что вы должны положиться, тем более, что цикл REPL действительно не существует, кроме как в интерактивном режиме интерпретатора.

+0

Получил это. Спасибо за ответ! – dazedconfused

+1

'stderr' и' stdout' являются буферизированными линиями; поэтому запись новой строки в 'stdout' покраснела. Но 'stderr' не был покраснел, поэтому вы не видите« бар »в своем терминале до тех пор, пока он не будет явно очищен * после запуска кода *, поэтому он печатается с опозданием. Если вы добавите новую строку к записанным данным, перед символом '4' появится' bar'. –

+0

@MartijnPieters: Просто увидел это, спасибо за разъяснение! – dazedconfused

4

В интерпретаторе python, когда вы что-то печатаете, он показывает результат на stdout и stderr.

Я тестировал его на своем python 3.4. Вот что я думаю, происходит

sys.std.write("foo") = > foo3 

Интерпретатор пишет «foo» в стандартный вывод. Затем интерпретатор печатает результат метода sys.stdout.write, который равен 3. Конечным результатом является foo3. Попробуйте sys.stdout.write ("foo \ n \ n"). И это может помочь вам увидеть.

sys.stderr.write("bar") => 
3 
bar 

Ошибка потока не так быстро, как выходы. Результат 3 из записи появляется сначала с новым символом строки. После этого панель печатается.

+0

Спасибо за объяснение! – dazedconfused

+1

Это не имеет никакого отношения к тому, как быстро работает 'stderr'. Это не медленнее или быстрее. И 'stdout', и' stderr' * * буферируются *, что означает, что они автоматически блокируются при написании новой строки. Никакая новая строка не записывается здесь, но REPL записывает количество написанных байтов с новой строкой. Поэтому 'sys.stdout' очищается новой строкой, написанной REPL, но' sys.stderr 'никогда не видит новую строку. После запуска кода Python явно очищает 'sys.stderr', так что только сообщение появляется в вашем терминале. –