配置python流的编码

有没有办法(在 python2 和 python3 上)配置tmp_stdout为使用不同的编码?


(我知道在 python3 上有编码参数,但这在 python2 上是不可能的)


import tempfile

import sys


original_stdout = sys.stdout


with tempfile.TemporaryFile(mode="w+") as tmp_stdout:

    # patch sys.stdout  

    sys.stdout = tmp_stdout


    print("📙")

    tmp_stdout.seek(0)

    actual_output = tmp_stdout.read()


# restore stdout

sys.stdout = original_stdout

也就是为什么在Windows的默认编码cp1252,即使我的命令提示符usese cp850。


这是使用 python3.6 在 windows 上运行时得到的错误


Traceback (most recent call last):

  File "Desktop\test.py", line 11, in <module>

    print("📙")

  File "C:\Users\AppData\Local\Programs\Python\Python36\lib\tempfile.py", line 483, in func_wrapper

    return func(*args, **kwargs)

  File "C:\Users\AppData\Local\Programs\Python\Python36\lib\encodings\cp1252.py", line 19, in encode

    return codecs.charmap_encode(input,self.errors,encoding_table)[0]

UnicodeEncodeError: 'charmap' codec can't encode character '\U0001f4d9' in position 0: character maps to <undefined>


千巷猫影
浏览 126回答 1
1回答

30秒到达战场

Windows 控制台默认为系统 OEM 代码页(例如西欧的 850),它支持传统的 DOS 程序和批处理脚本,但现在没有实际用途。Python 3.6+ 使用控制台的 Unicode API。在内部这是 UTF-16LE,但在缓冲区/原始层,它显示为 UTF-8 以实现跨平台兼容性。要在 Python 2 中获得类似的支持,请安装并启用win_unicode_console。对于非控制台文件,Python 3 中的默认编码是系统 ANSI 代码页(例如西欧的 1252)。这是 Windows 中许多文本编辑器(例如记事本)的经典默认设置。要获得完整范围的 Unicode,请使用参数 覆盖编码encoding='utf-8'。为了在 Python 2 和 3 中支持这一点,您可以fileno()使用 io 模块包装文件描述符(即),该模块在 Python 3 发布 (2.6+) 时向后移植。例如:import sysimport tempfilewith tempfile.TemporaryFile(mode='w+b') as tmp:&nbsp; &nbsp; tmp_stdout = io.open(tmp.fileno(), mode='w+', encoding='utf-8', closefd=False)&nbsp; &nbsp; sys.stdout, original_stdout = tmp_stdout, sys.stdout&nbsp; &nbsp; try:&nbsp; &nbsp; &nbsp; &nbsp; print("📙")&nbsp; &nbsp; finally:&nbsp; &nbsp; &nbsp; &nbsp; sys.stdout = original_stdout&nbsp; &nbsp; tmp_stdout.seek(0)&nbsp; &nbsp; actual_output = tmp_stdout.read()请注意,临时文件以“w+b”模式打开,这避免了 Windows 上 Python 2 中 C 运行时的低级文本模式,这是我们不想要的,因为它处理字符 0x1A(即 Ctrl+Z)作为文件结束标记(DOS 和 CP/M 的遗产)并进行换行转换(例如 LF -> CRLF)。io 模块TextIOWrapper已经实现了换行转换。另请注意,io.open调用使用的closefd=False原因tmp已在with语句中自动关闭。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python