Python 中如何设置 stdout 的编码?

Python开发中,有时候进程的运行环境里,locale 会被设置成只支持 ASCII 字符集的(比如)。这时候 Python 就会把标准输出和标准错误的编码给设置成 ascii,造成输出中文时报错。

一种解决办法是设置支持 UTF-8 的 locale,但是那需要在 Python 进程启动前设置。启动之后,初始化过了,再设置 locale也不会重新初始化那些对象。

另一种办法是往 sys.stdout.buffer 这种地方直接写 bytes。理论上完全没问题,但是写起程序来好累……

我就去找了一下怎么优雅地弄一个新的 sys.stdout 出来。Python 3 的 I/O 不再使用 C 标准库的 I/O 函数,而是直接使用OS 提供的接口。封装位于 io 这个模块里边,有带缓冲的,不带缓冲的,二进制的,文本的。

研究了一下文档可知,sys.stdout 是个 io.TextIOWrapper,有个 buffer 属性,里边是个 io.BufferedWriter。我们用它造一个新的 io.TextIOWrapper,指定编码为 UTF-8:

import sysimport io

def setup_io():

sys.stdout = sys.__stdout__ = io.TextIOWrapper(

sys.stdout.detach(), encoding=’utf-8’, line_buffering=True)

sys.stderr = sys.__stderr__ = io.TextIOWrapper(

sys.stderr.detach(), encoding=’utf-8’, line_buffering=True)

这里除了可以设置编码之外,也可以设置错误处理和缓冲。所以这个技巧也可以用来容忍编码错误、改变标准输出的缓冲(不需要在启动的时候加 -u 了)。

其实这样子还是不够彻底。Python 在很多地方都有用到默认编码。比如 subprocess,指定 universal_newlines=True 时Python 会自动给标准输入、输出、错误编解码,但是呢,在 Python 3.6 之前,这里的编码是不能手动指定的。还有参数的编码,也是不能指定的(不过可以传 bytes 过去)。

所以,还是想办法去设置合适的 locale 更靠谱……

文章来源: 依云’s Blog

时间: 2024-12-20 23:12:29

Python 中如何设置 stdout 的编码?的相关文章

Python中的字符串与字符编码

原文地址:点击这里 本节内容: 前言 相关概念 Python中的默认编码 Python2与Python3中对字符串的支持 字符编码转换 一.前言 Python中的字符编码是个老生常谈的话题,同行们都写过很多这方面的文章.有的人云亦云,也有的写得很深入.近日看到某知名培训机构的教学视频中再次谈及此问题,讲解的还是不尽人意,所以才想写这篇文字.一方面,梳理一下相关知识,另一方面,希望给其他人些许帮助. Python2的 默认编码 是ASCII,不能识别中文字符,需要显式指定字符编码:Python3的

在Windows的CMD中如何设置支持UTF8编码?

这个问题很多人开始都会不知道,当然包括曾经的我,当用到的时候,只好求助于伟大的股沟和度娘了.网上有设置的方法,但说明确不够详细系统,说设置字体 为:Lucida Console.问题是,在默认方式下,只有点阵字体,哪有什么Lucida Console.所以,在自己成功设置后,拿出来和大家分享下过程,下面就让我们找出Lucida Console来设置吧. 这里需要先了解些内容: CHCP CHCP是MS DOS中的命令,用来显示或设置活动代码页编号的.用法是: CHCP [nnn] 其中nnn指定

python中颜色设置

实现过程: 终端的字符颜色使用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\033来表示(ESC是ASCII码用十进制表示是27,用八进制表示就是033) 书写格式: 开头部分:\033[显示方式:前景色:背景色m + 结尾部分:\033[0m 注意:开头部分的三个参数:显示方式.前景色.背景色是可选参数,但是必须要写一个. 由于三个参数不同含义的数值都是唯一的没有重复,所以参数的书写并没有顺序,系统都能够识别. 数值表示的参数含义: 前景色 背景

Python中,关于读取文件编码解码的问题

UnicodeDecodeError: 'gbk' codec can't decode byte 0xb1 in position 94: illegal multibyte sequence 有时候用open()方法打开文件读取文件的时候会出现这个问题:'GBK'编×××无法解码94号位置的字节0xb1:非法多字节序列.错误信息提示了使用"GBK"解码. 1.分析 pycharm自动使用的是'UTF-8'编码,好像没有什么问题,为什么会出现这个错误呢.结果查了下open()函数的注

python中的system函数与编码

在调用os.system执行命令时,发现system不能接受unicode的命令.那么命令中却又包含以unicode表示的中文等字符怎么办? ——方法就是将unicode转化为utf8 path = u'我的文件.txt' cmd = 'process' cmd += ' '+ path.encode('utf8') os.system(cmd)

字符、字符集、编码,以及它们python中会遇到的一些问题(上)

在看了很多的博客文章之后,总结整理得到了以下文章,非常感谢这些无私奉献的博主! 文章末尾有本文引用的文章的链接,如果有漏掉的文章引用,可以发邮件联系我,随后再次附上链接! 侵删!!! 这一部分是上篇,主要讲的是字符.字符集和字符编码的一些概念,以及他们在python中的一些简单的代码示例,偏向于概念. 下篇会说编码和解码部分,以及在python中会遇到的一些编码问题,偏向于实际应用一点. 这绝对是个源远流长的大坑,对于新手来说恶心致死(尤其是windows)........... 一.字符.字符

python中的函数式编程与装饰器

2.1 python中的函数式编程 函数式编码的特点 把计算视为函数而非指令 纯函数式编程,不需要变量,没有副作用,测试简单 支持高阶函数,代码简洁 python支持的函数式编程 不是纯函数式编码:允许有变量 支持高阶函数:函数也可以作为变量传入 支持闭包:有了闭包就能返回函数 有限度地支持匿名函数 2.2 python中高阶函数 函数名可以作为变量,如 高阶函数:只能接收函数作为参数的函数 变量可以是指向函数 函数的参数可以接收变量 一个函数可以接收另一个函数作为参数 能接收函数作为参数的函数

使用ctypes在Python中调用C++动态库

使用ctypes在Python中调用C++动态库 入门操作 使用ctypes库可以直接调用C语言编写的动态库,而如果是调用C++编写的动态库,需要使用extern关键字对动态库的函数进行声明: #include <iostream> using namespace std; extern "C" { void greet() { cout << "hello python" << endl; } } 将上述的C++程序编译成动态链

python中的base64加密解密

介绍 Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法.可查看RFC2045-RFC2049,上面有MIME的详细规范. Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息.采用Base64编码具有不可读性,需要解码后才能阅读. Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各