如何得到\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
模块旨在为抽象基类RawIOBase
, BufferedIOBase
和TextIOBase
提供所有类文件对象的跨平台和跨实现(CPython,PyPy,IronPython,Jython)规范。 它在_pyio
模块中包含一个参考纯Python实现。 原始io.FileIO
实现的共同点是一组低级别的POSIX系统调用,例如read
和write
,这消除了CRT视频不一致的问题。 在Windows上,POSIX层只是CRT的低I / O层,但至少这仅限于单个平台的怪癖。
其中一个Windows怪癖是在其POSIX I / O层中使用非标准的文本和二进制模式。 Python通过始终使用二进制模式并在stdio文件描述符1上调用setmode
来解决此问题。
Python可以通过实现WinFileIO
注册子类避免使用Windows CRT进行I / O。 这个问题12939有一个建议的补丁。 另一个例子是win_unicode_console模块,它实现了WindowsConsoleRawReader
和WindowsConsoleRawWriter
类。
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