在 windows 下运行 python 命令行程序容易遇到编码问题,处理不好就会出现乱码。
Win10 的 cmd 命令行下的标准输入输出编码是 utf-8 编码,但在启用管道和文件重定向时,标准输入输出又会变成 gbk 编码。我们可以在程序中加入调试语句查看标准输入输出的编码:
import sysprint("标准输入流的编码是:", sys.stdin.encoding)print("标准输出流的编码是:", sys.stdout.encoding)

当没有管道时,程序输出为:

当有管道作为输入时,标准输入会发生变化:

当将输出重定向时,标准输入输出都会发生变化:

Python 的 print 是受标准输入输出编码影响的,而标准输入输出的编码又会受所使用的终端影响。在 cmd 下,标准输入输出编码默认是 utf-8,当有管道和重定向时,标准输入输出会变成 gb2312。
Python 在 windows git-bash 下表现的又不一样,同样的测试代码,在 git-bash 下执行效果如下:

git-bash 下,标准输入输出的编码变成了 gbk,因为 git-bash 终端使用的是 utf-8 ,当程序编码与终端编码不一致时就会出现乱码。
解决乱码的办法有两种,一是调整 git-bash终端的编码:

调整完,程序执行就不显示乱码了:

第二种方法是不修改终端编码,但修改程序中标准输入输出的编码:
import ioimport syssys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
将标准输入输出的编码改得和终端编码一致就不会产生乱码了。git-bash 可以调整终端编码,但 cmd 没法调整终端编码。可以推断出 Win10 下 cmd 终端的编码是 utf-8,虽然 cmd 中使用 chcp 命令显示的是 936 (936 代表的是 gb2312 , 65001 代表的是 utf-8),但 chcp 并不可行。

我一直以为 cmd 终端的编码是 gbk 或 gb2312,但测试出来的结果是 cmd 用来显示的编码是 utf-8,管道和重定向使用的是 gb2312
默认 python 在 git-bash 下输出中文会出现乱码,为避免乱码问题,可以将标准输入输出的编码改为 utf-8 ,也可以使用以下函数来简化操作:
import sysimport ioimport platformimport osdef change_default_encoding():"""判断是否在 windows git-bash 下运行,是则使用 utf-8 编码"""if platform.system() == 'Windows':terminal = os.environ.get('TERM')if terminal and 'xterm' in terminal:sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
全文完。
如果转发本文,文末务必注明:“转自微信公众号:生有可恋”。




