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 · 12290 次点击
    这是一个创建于 3216 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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  
       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   ·   实用小工具   ·   1013 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 20:02 · PVG 04:02 · LAX 12:02 · JFK 15:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.