Печать LF с Python 3 на стандартный вывод Windows
Как получить \n
печатать на стандартный вывод на Windows? Этот код работает в Python 2, но не в Python 3:
# set sys.stdout to binary mode on Windows
import sys, os, msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
# the length of testfile created with
# python test_py3k_lf_print.py > testfile
# below should be exactly 4 symbols (23 0A 23 0A)
print("#\n#")
1 ответ
Python 3 уже настраивает стандартный ввод / вывод в двоичном режиме, но у него есть собственная реализация ввода / вывода, которая выполняет перевод новой строки. Вместо того, чтобы использовать print
, который требует файл в текстовом режиме, вы можете вызвать вручную sys.stdout.buffer.write
использовать бинарный режим BufferedWriter
, Если вам нужно использовать print
тогда вам понадобится новая оболочка ввода / вывода текста, которая не использует универсальные переводы строк. Например:
stdout = open(sys.__stdout__.fileno(),
mode=sys.__stdout__.mode,
buffering=1,
encoding=sys.__stdout__.encoding,
errors=sys.__stdout__.errors,
newline='\n',
closefd=False)
поскольку closefd
false, закрытие этого файла не закроет оригинал sys.stdout
дескриптор файла. Вы можете использовать этот файл явно через print("#\n#", file=stdout)
или заменить sys.stdout = stdout
, Оригинал доступен как sys.__stdout__
,
Фон
Python 3 io
Модуль был разработан для обеспечения кроссплатформенности и кросс-реализации (CPython, PyPy, IronPython, Jython) для всех файловоподобных объектов в терминах абстрактных базовых классов. RawIOBase
, BufferedIOBase
, а также TextIOBase
, Он включает эталонную чистую реализацию Python в _pyio
модуль. Общий знаменатель для сырья io.FileIO
реализация представляет собой набор системных вызовов низкого уровня POSIX, таких как read
а также write
, что устраняет проблему несоответствий CRT stdio. В Windows уровень POSIX - это просто низкий уровень ввода-вывода CRT, но по крайней мере он ограничен особенностями одной платформы.
Одна из особенностей Windows - наличие нестандартного текстового и двоичного режимов в слое ввода / вывода POSIX. Python решает эту проблему, всегда используя двоичный режим и вызывая setmode
в файловых дескрипторах stdio 1.
Python может избежать использования Windows CRT для ввода / вывода, реализовав WinFileIO
зарегистрированный подкласс RawIOBase
, Предлагается патч для этого в выпуске 12939. Другим примером является модуль win_unicode_console, который реализует WindowsConsoleRawReader
а также WindowsConsoleRawWriter
классы.
1. Это вызвало проблемы для программ, которые встраивают Python и ожидают, что stdio будет использовать текстовый режим по умолчанию. Например, в двоичном режиме печать широких символов больше не приводит к char
как это происходит в текстовом режиме ANSI, и он, конечно, не печатает, используя WriteConsoleW
как было бы в текстовом режиме UTF-16. Например:
Python 2.7.10 (default, May 23 2015, 09:44:00)
[MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys, os, msvcrt, ctypes
>>> ctypes.cdll.msvcr90.wprintf(b'w\x00i\x00d\x00e\x00\n\x00')
wide
5
>>> msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
16384
>>> ctypes.cdll.msvcr90.wprintf(b'w\x00i\x00d\x00e\x00\n\x00')
w i d e
5