有过稍长时间 Python 开发的同学可能都听说过 ipython,或者说叫 jupyter 更对一些。jupyter 给我们提供了一个方便开发和调试 Python 代码的环境,而且可以实时方便得看到代码的输出,代码块和打印块是分开的,而且还有加亮效果,更是有多种显示方案。

但是,今天就被这个平时用得爽爽的工具甩了一刀,一脸的不乐意。问题的起因是这样的:

今天尝试处理一个文本,然后就老套路啦,读取文本,处理文本,写出文本。然而,问题就在这样的简单常规操作中发生了,在读取文本的时候居然抛出了异常:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)

瞬间有点老司机出车祸的感觉,都写了这么久的 Python 代码了,怎么还会出现编码错误的问题。那,既然有问题,那就要解决了,根据网络上的提示,我首先先看了一下自己的环境编码:

好,既然是这样,那就修改一下环境编码吧。怎么修改,既然有 getdefaultencoding,那应该可以有 setdefaultencoding 吧,试试:

额,居然没有这个属性!!!怎么办,继续谷歌,然后发现原来 setdefaultencoding 这个函数在启动的时候就被干掉了,所以需要重新加载一下 sys 模块,有效的做法是:

这下我们再重新看一下环境编码:

好像可以的样子,继续跑跑代码,发现终于跑通了,继续爽...然而,还没爽多久就发现坑来了,出现的问题就是 print 打印的字符串不见了!!!尝试了好多好多方法,最后才发现原来都打印到后面的控制台去了,真是服了。秉着求知的态度去谷歌了好几把,终于发现了问题,原来 jupyter 启动的时候 print 的输入和输出多了一些重定向,当我使用 reload 的时候其实就是重置了输入和输出,这样的话,print 肯定就打印到控制台去了,看到一个很简单的解决办法,就是:

然后重启一下 jupyter,再跑代码,然后发现一切都正常了。然而,看到这冗长的设置,我不禁要问这样真的合适吗?难道这是正确的做法么?

最佳实践

说了这么多,如果不迁移到 Python 3,能怎么做呢?有这么几个建议:

如果你想更简单一些的话,还可以参考我的这篇文章:设置Python系统默认编码,一劳永逸。

References