立即停止在 Python 中使用 setdefaultencoding('utf-8'), 以及为什么

2016-02-01 11:54:03 +08:00
 ernest

http://blog.ernest.me/post/python-setdefaultencoding-unicode-bytes

我看了下现在(包括 V2EX 上)还在使用 sys.setdefaultencoding('utf-8') 来解决中文编码问题的有很多,而且很多人在使用的时候压根没有意识到带来的 bug。特写此文与大家讨论。

12300 次点击
所在节点    Python
27 条回复
florije
2016-02-01 12:03:39 +08:00
一点都没说到点上,建议搜下 v2 历史,有个帖子说到了,建议好好看看再 append 。
zjq426
2016-02-01 12:04:08 +08:00
1. 这么用确实方便
2. 这么用确实用 dict 的时候遇到过问题
3. 这么用确实有诡异的疑似 bug 出现,或者说,出现了一些和 naive 理解上偏差

好吧我以后不这么用了,我错了。
所有 text string 都应该是 unicode 类型,而不是 str
nyanyh
2016-02-01 12:07:04 +08:00
所以 Python 3 是没问题咯
zjq426
2016-02-01 12:09:30 +08:00
然而你就不能利用 python2 提供的 unicode=>ascii 转换的便利了
wgwang
2016-02-01 12:10:05 +08:00
python3, python3, python3
重要的事说 3 遍
aivier
2016-02-01 12:26:12 +08:00
隔壁 NodeJS 路过看看→_→...GBK 也是比较麻烦的事,要用 iconv
nooper
2016-02-01 12:45:21 +08:00
80 %以上的代码是不良习惯, 10 是 hacking code 。 10 编的是实质性的代码。奇怪的 hacking code 为什么要写大家一向是 badu 出来的
pynix
2016-02-01 12:49:46 +08:00
python3 才是正确的选择。。。
ernest
2016-02-01 13:56:41 +08:00
@florije 我刚搜索了下,没找到专门对这块做解释的帖子,如你方便还有劳告知。多谢!
florije
2016-02-01 14:18:41 +08:00
@ernest 其实很简单,关键点在 print
ernest
2016-02-01 14:35:58 +08:00
@florije 能告知那篇帖子的地址或者关键词吗,我来找来读下。谢谢!
关键点并不在 print 上吧?任何涉及到 encode/decode 的操作都会出问题。
FrankFang128
2016-02-01 14:40:34 +08:00
Python 永远的痛
ernest
2016-02-01 14:41:41 +08:00
@FrankFang128 也还好,能按照最佳实践来不会出问题。只能说 Python 给的糖太多了。
tt0411
2016-02-01 14:44:02 +08:00
python2 脚本开头习惯性添加:
from __future__ import unicode_literals
loading
2016-02-01 14:44:17 +08:00
python 最不爽就是这里!
glasslion
2016-02-01 15:32:41 +08:00
@ernest 支持。我早就想写篇报道,把 setdefaultencoding 批判一番了。 可惜,太懒...
ernest
2016-02-01 15:38:47 +08:00
@tt0411 这么做会有一个兼容性问题:

demo1.py
```python
# encoding: utf-8
hello = '你好'

```

demo2.py
```python
# encoding: utf-8
from __future__ import unicode_literals
import demo1
world = '世界'
print demo1.hello + world

```
这时就会有错。

而控制自己的代码都引入是没问题的,但第三方库就没法控制了。

因此还是走最佳实践的几条建议比较妥当。
ernest
2016-02-01 15:39:12 +08:00
@glasslion 不晚!
florije
2016-02-01 15:53:52 +08:00
@ernest 首先三个概念:
1. str is for bytes, NOT strings
2. unicode is for strings
3. UTF-8, UTF-16, and UTF-32 are serialization formats — NOT Unicode
然后尽量别用 print 打印比较。
然后再看看上面的兼容性问题~以及博客里面说的内容~
florije
2016-02-01 16:00:03 +08:00
@ernest 然后你再看看你所说的 encode , decode 是什么情况?
encode(): Gets you from Unicode -> bytes
decode(): Gets you from bytes -> Unicode
so ,这么来看问题都一点点解决了吧?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/254744

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX