为了账号安全,请及时绑定邮箱和手机立即绑定

配置python流的编码

配置python流的编码

千巷猫影 2021-11-09 15:01:36
有没有办法(在 python2 和 python3 上)配置tmp_stdout为使用不同的编码?(我知道在 python3 上有编码参数,但这在 python2 上是不可能的)import tempfileimport sysoriginal_stdout = sys.stdoutwith 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 stdoutsys.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>
查看完整描述

1 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

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 sys

import tempfile


with tempfile.TemporaryFile(mode='w+b') as tmp:

    tmp_stdout = io.open(tmp.fileno(), mode='w+', encoding='utf-8', closefd=False)


    sys.stdout, original_stdout = tmp_stdout, sys.stdout

    try:

        print("📙")

    finally:

        sys.stdout = original_stdout


    tmp_stdout.seek(0)

    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语句中自动关闭。


查看完整回答
反对 回复 2021-11-09
  • 1 回答
  • 0 关注
  • 124 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信