Найти - Пользователи
Полная версия: Реализация оператора print
Начало » Python для новичков » Реализация оператора print
1 2
koluna
Всем привет!

Не подскажите, где можно посмотреть на реализацию данного оператора (Python 2.x)?
Чем принципиально отличается вывод данных с помощью print от вывода данных через sys.stdout.write()?
Когда при работе с sys.stdout происходит вывод из буфера? Каков размер буфера?
py.user.next
koluna
Не подскажите, где можно посмотреть на реализацию данного оператора (Python 2.x)?
В исходниках.
git://github.com/akheron/cpython.git
python.org. python 2.7.9

koluna
Чем принципиально отличается вывод данных с помощью print от вывода данных через sys.stdout.write()?
Он может вообще в другой поток выводить.
>>> import sys
>>> 
>>> print >>sys.stderr, 'test'
test
>>>

>>> print 1, 2, 3
1 2 3
>>> sys.stdout.write(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: function takes exactly 1 argument (3 given)
>>>

koluna
Когда при работе с sys.stdout происходит вывод из буфера?
Вообще - когда буфер заполняется, но можно и построчную буферизацию установить, и вообще отключить буфер.

koluna
Каков размер буфера?
Зависит от системы, обычно ставят такой же, как и BUFSIZ в сишном компиляторе.

В третьем питоне
>>> import io
>>> io.DEFAULT_BUFFER_SIZE
8192
>>>
koluna
py.user.next
В исходниках.

Да понятно, что в исходниках, я имел в виду конкретный файл
Вдруг кто-нибудь помнит где искать, а то файлов-то много…

py.user.next
Он может вообще в другой поток выводить.

Это известно.

py.user.next
Вообще - когда буфер заполняется, но можно и построчную буферизацию установить, и вообще отключить буфер.

Вот тут хотелось бы поподробнее…

py.user.next
В третьем питоне
В 2.7.9 тоже: https://docs.python.org/2/library/io.html
Изменить размер буфера можно, присвоив io.DEFAULT_BUFFER_SIZE другое значение?

Какая буферизация включена по умолчанию? Строковая?
#!/usr/bin/python
#-*- coding: utf-8 -*-
import sys
import io
import time
# Размер буфера ввода-вывода.
print 'io.DEFAULT_BUFFER_SIZE =', io.DEFAULT_BUFFER_SIZE
# Строка на экране появляется сразу.
sys.stdout.write('string 1\r\n')
time.sleep(3)
# Строка на экране появляется через 6 секунд после запуска программы.
sys.stdout.write('string 2')
time.sleep(3)
koluna
Эти строки появляются на экране сразу (в них есть конец строки, т. к. у нас, судя по всему, строковая буферизация):
sys.stdout.write('string 1\r\n')
sys.stdout.write('string 2\n')

а вот эта строка почему-то теряется и не выводится даже при завершении программы:
sys.stdout.write('qwerty\r')
py.user.next
koluna
Да понятно, что в исходниках, я имел в виду конкретный файл

Python/ast.c
static stmt_ty
ast_for_print_stmt(struct compiling *c, const node *n)

koluna
Вот тут хотелось бы поподробнее…
koluna
Изменить размер буфера можно, присвоив io.DEFAULT_BUFFER_SIZE другое значение?

https://docs.python.org/2/library/io.html#io.open
buffering is an optional integer used to set the buffering policy. Pass 0 to switch buffering off (only allowed in binary mode), 1 to select line buffering (only usable in text mode), and an integer > 1 to indicate the size of a fixed-size chunk buffer. When no buffering argument is given, the default buffering policy works as follows:

https://docs.python.org/2/library/io.html#io.BufferedWriter
Передаётся размер буфера при создании потока.

https://docs.python.org/2/library/io.html#io.TextIOWrapper
Передаётся включение построчной буферизации.

koluna
Какая буферизация включена по умолчанию? Строковая?
Для stdin и stdout включается полная буферизация, а строковая может быть включена для stderr.
koluna
py.user.next
Для stdin и stdout включается полная буферизация, а строковая может быть включена для stderr.

А где про это сказано?

Все-таки не понятна ситуация с выводом строк (пост №4).
Почему, если для stdout включена полная буферизация, то строки на экране появляются не только при заполнении буфера, вызове flush(), но и если строки содержат ‘\r\n’, ‘\n’?

Правильно ли я понимаю, что если включена полная буферизация, то строки на экране после sys.stdout.write() могут появяться только в следующих случаях (https://docs.python.org/2/library/io.html#io.BufferedWriter)?
1) Заполнение буфера.
2) Вызов sys.stdout.flush().
3) Разрушение объекта stdout (завершение программы).
py.user.next
koluna
А где про это сказано?
C89 (draft)
4.9.3 Files



At program startup, three text streams are predefined and need not
be opened explicitly — standard input (for reading conventional
input), standard output (for writing conventional output), and
standard error (for writing diagnostic output). When opened, the
standard error stream is not fully buffered; the standard input and
standard output streams are fully buffered if and only if the stream
can be determined not to refer to an interactive device.

Сейчас проверил, строковая буферизация там и для sys.stdout, и для sys.stderr.
Но если сделать вот так:
t.py
#!/usr/bin/env python
# coding: utf-8
 
import sys
import time
 
print 'a'
time.sleep(5)

В консоли:
t.py > out.txt
то включается полная, потому что вывод не привязан к терминалу.

koluna
Почему, если для stdout включена полная буферизация
Строковая там, потому что обнаружен терминал.

Они могли, конечно, реализовать работу со стандартными потоками и в обход стандартной сишной библиотеки, прямо через системные вызовы. Тогда буферизация вообще может работать как угодно. Но пока что всё похоже на стандартное поведение для сишных программ.


koluna
1) Заполнение буфера.
2) Вызов sys.stdout.flush().
3) Разрушение объекта stdout (завершение программы).
Всё таки разрушение объекта и завершение программы - это разные вещи. При нормальном завершении программы любая сишная программа выталкивает потоки по стандарту.
Но удаление объекта тоже выталкивает, это уже в питоне определено. Скорее всего он файл просто закрывает, а при закрытии буфер выталкивается.

koluna
а вот эта строка почему-то теряется и не выводится даже при завершении программы:
sys.stdout.write('qwerty\r')
У меня сразу выводится.
koluna
py.user.next
У меня сразу выводится.

Не выводится ни при завершении, ни при использовании flush().
Влияет именно символ ‘\r’.
Возможно, от платформы зависит?
У меня Ubuntu 10.04, Python 2.6.5.
py.user.next
>>> import sys
>>> 
>>> sys.stdout.write('qwerty\r')
>>> ty
>>> sys.version_info
(2, 6, 3, 'candidate', 1)
>>>

koluna
Не выводится ни при завершении, ни при использовании flush().
А где выполняешь строку?
koluna
py.user.next
А где выполняешь строку?

Когда в скрипте выполняю - ничего не выводится.
Когда в интерпретаторе, то выводится “ty”.

>>> import sys
>>> sys.stdout.write('qwerty\r')
>>> ty
>>> sys.version_info
(2, 6, 5, 'final', 0)

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB