Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 20, 2015 08:42:25

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализация оператора print

Всем привет!

Не подскажите, где можно посмотреть на реализацию данного оператора (Python 2.x)?
Чем принципиально отличается вывод данных с помощью print от вывода данных через sys.stdout.write()?
Когда при работе с sys.stdout происходит вывод из буфера? Каков размер буфера?

Офлайн

#2 Фев. 20, 2015 10:58:00

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Реализация оператора print

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
>>>



Отредактировано py.user.next (Фев. 20, 2015 11:02:16)

Офлайн

#3 Фев. 20, 2015 11:48:29

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализация оператора print

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)

Офлайн

#4 Фев. 20, 2015 12:17:54

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализация оператора print

Эти строки появляются на экране сразу (в них есть конец строки, т. к. у нас, судя по всему, строковая буферизация):

sys.stdout.write('string 1\r\n')
sys.stdout.write('string 2\n')

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

Офлайн

#5 Фев. 20, 2015 14:00:46

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Реализация оператора print

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.



Отредактировано py.user.next (Фев. 20, 2015 14:01:01)

Офлайн

#6 Фев. 20, 2015 19:17:08

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализация оператора print

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 (завершение программы).

Офлайн

#7 Фев. 20, 2015 22:59:38

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Реализация оператора print

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')
У меня сразу выводится.



Отредактировано py.user.next (Фев. 20, 2015 23:09:42)

Офлайн

#8 Фев. 21, 2015 17:43:28

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализация оператора print

py.user.next
У меня сразу выводится.

Не выводится ни при завершении, ни при использовании flush().
Влияет именно символ ‘\r’.
Возможно, от платформы зависит?
У меня Ubuntu 10.04, Python 2.6.5.

Офлайн

#9 Фев. 21, 2015 23:37:03

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10015
Репутация: +  857  -
Профиль   Отправить e-mail  

Реализация оператора print

>>> import sys
>>> 
>>> sys.stdout.write('qwerty\r')
>>> ty
>>> sys.version_info
(2, 6, 3, 'candidate', 1)
>>>

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



Офлайн

#10 Фев. 22, 2015 21:17:14

koluna
Зарегистрирован: 2014-07-08
Сообщения: 30
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализация оператора print

py.user.next
А где выполняешь строку?

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

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

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version