用Python 3打印LF到stdout

如何得到\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#") 

Python 3已经以二进制模式配置了标准I / O,但是它有自己的I / O实现来执行新行翻译。 而不是使用需要文本模式文件的print ,您可以手动调用sys.stdout.buffer.write来使用二进制模式BufferedWriter 。 如果您需要使用print ,那么您将需要一个不使用通用换行符的新文本I / O包装器。 例如:

 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模块旨在为抽象基类RawIOBaseBufferedIOBaseTextIOBase提供所有类文件对象的跨平台和跨实现(CPython,PyPy,IronPython,Jython)规范。 它在_pyio模块中包含一个参考纯Python实现。 原始io.FileIO实现的共同点是一组低级别的POSIX系统调用,例如readwrite ,这消除了CRT视频不一致的问题。 在Windows上,POSIX层只是CRT的低I / O层,但至少这仅限于单个平台的怪癖。

其中一个Windows怪癖是在其POSIX I / O层中使用非标准的文本和二进制模式。 Python通过始终使用二进制模式并在stdio文件描述符1上调用setmode来解决此问题。

Python可以通过实现WinFileIO注册子类避免使用Windows CRT进行I / O。 这个问题12939有一个建议的补丁。 另一个例子是win_unicode_console模块,它实现了WindowsConsoleRawReaderWindowsConsoleRawWriter类。


1.这给嵌入Python的程序带来了问题,并希望stdio使用默认的文本模式。 例如,在二进制模式下,打印宽字符的字符串不再像在ANSI文本模式下那样强制转换为char ,而是使用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') wide 5