立即停止在 Python 中使用 setdefaultencoding('utf-8'), 以及为什么 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
ernest
V2EX    Python

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

  •  3
     
  •   ernest
    heshiyou 2016-02-01 11:54:03 +08:00 12783 次点击
    这是一个创建于 3592 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    http://click.pocoo.org/5/python3/

    https://github.com/PythonCharmers/python-future/issues/22
    ming2281
        25
    ming2281  
       2016-02-01 20:09:03 +08:00 via Android
    py2 中有别的语言没有的编码问题,
    属于基本功了,
    不至于动用 sys
    fy
        26
    fy  
       2016-02-01 20:51:37 +08:00
    危言耸听!
    另外讲道理还是赶紧迁移到 Python3
    latyas
        27
    latyas  
       2016-02-02 11:38:33 +08:00
    defaultencoding = ascii 难道就没问题了?
    = utf-8 才是本该正确的。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5531 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 03:18 PVG 11:18 LAX 19:18 JFK 22:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86