V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
geew
V2EX  ›  问与答

我以为我不会被 python 的编码折磨了, 看来我还是太嫩了, 大家帮我看看这个问题吧,谢谢了

  •  3
     
  •   geew · 2014-05-13 10:53:06 +08:00 · 3631 次点击
    这是一个创建于 3646 天前的主题,其中的信息可能已经有所发展或是发生改变。
    In [43]: '%s-%s' % ('中国', u'2323')
    ---------------------------------------------------------------------------
    UnicodeDecodeError Traceback (most recent call last)
    /home/gowin/yunfan/Kuaibi/gateway/<ipython-input-43-816b251553ea> in <module>()
    ----> 1 '%s-%s' % ('中国', u'2323')

    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

    In [44]: '%s-%s' % (u'中国', '2323')
    Out[44]: u'\u4e2d\u56fd-2323'

    In [45]: '%s-%s' % ('中国', '2323')
    Out[45]: '\xe4\xb8\xad\xe5\x9b\xbd-2323'

    In [46]: '%s-%s' % (u'中国', u'2323')
    Out[46]: u'\u4e2d\u56fd-2323'


    为毛第一个会报错呢??
    PS: 遇到这类型的问题怎么做才是最佳的解决方案呢? 就是不知道你的字符串是什么编码,然后你要做连接操作.
    第 1 条附言  ·  2014-05-13 13:10:40 +08:00
    谢谢大家的帮忙了. 我总结一下回复吧. 也备注下...

    1. 一般编码问题产生的异常会是这样的:
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
    这个问题最直接的原因就是这行语句: In [80]: '中国'.decode('ascii')
    - 简单来讲就是python2在使用默认的编码对中文进行unicode编码时候出错了. 在python2里面, 中文的unicode编码应该指定utf8(推荐)

    2. 在格式化字符串中, 如果有unicode字符串存在, 格式化后的字符串python都会默认转换为unicode, 因此会涉及编码的问题. 这点要注意

    3. 在程序内部尽量明文使用unicode(即明确decode('utf8')), 输出到外部要encode('utf8')

    以上, 大家看说得对不对
    第 2 条附言  ·  2014-05-13 18:03:12 +08:00
    - '%s-%s' % ('中国', u'2323')
    报错的原因就是其实这里真正执行的是这样子的:
    [ERROR]: '%s-%s' % ('中国'.decode('acsii'), u'2323')
    理由: 格式化字符串中有u'2323', 因此格式化后的字符串是unicode, python会用默认进行编码, 而python2的默认编码方式是acsii
    第 3 条附言  ·  2014-05-13 18:03:34 +08:00
    好吧 是acsii
    第 4 条附言  ·  2014-05-13 18:03:58 +08:00
    ascii 这个 哈哈
    14 条回复    2015-03-29 02:10:31 +08:00
    skydiver
        1
    skydiver  
       2014-05-13 10:59:24 +08:00
    报错是因为中文没法用ascii解码

    所以必须指定是unicode,或者用python3吧
    duzhe0
        2
    duzhe0  
       2014-05-13 11:14:16 +08:00
    源代码用utf-8编码,并且在文件第二行加上:
    # -*- coding: utf-8 -*-
    duzhe0
        3
    duzhe0  
       2014-05-13 11:16:59 +08:00
    不好意思, 我发的解决不了问题
    loading
        4
    loading  
       2014-05-13 11:22:28 +08:00 via Android
    先检测出编码,再连接!
    yxjxx
        5
    yxjxx  
       2014-05-13 11:27:35 +08:00
    遇到过类似问题,写过一篇简单的总结. http://yxjxx.me/basic-character-encoding 适用于python2
    Ever
        6
    Ever  
       2014-05-13 11:31:44 +08:00
    省u加from __future__ import unicode_literals
    不然除了英文数字符号统统加u
    aurorawu
        7
    aurorawu  
       2014-05-13 11:42:02 +08:00
    In [43]: '%s-%s' % ('中国', u'2323')
    '' + u'' == u'' 这里是中文(字节)转成unicode(字符) 所以decode 但是中文用ascii解码会报错 @skydiver +1
    Sylv
        8
    Sylv  
       2014-05-13 11:49:45 +08:00   ❤️ 5
    第一个报错是因为有一个参数 u'2323' 是 Unicode,所以在格式化字符串的时候会将所有 String 都转换为 Unicode 输出,而 Python2 默认编码是 ascii,用 ascii 编码转换 String 类型的 '中国' 时就出错了,需要用 utf-8 编码才不会出问题:'中国'.decode('utf-8')。
    第二个没问题是因为 u'中国'已经是 Unicode 了就不用转换了,而 '2323' 是可以用默认的 ascii 编码转换成 Unicode 的,所以不会出错。
    第三个是因为所有参数都是 String 类型的,那么格式化后输出的也是 String 类型,没有涉及到编码转换,所以没有问题。

    曾经也被 Python2 的编码坑了很多次,我后来的经验是:代码里所有写的字符串不管中英文都在前面加u,处理为 Unicode;然后所有输入都 decode 为 Unicode,内部处理全用 Unicode,输出时再 encode 为 String。这样可以尽量避免编码出错,以后也更好迁移到 Python3。
    walleL
        9
    walleL  
       2014-05-13 12:44:42 +08:00
    @Sylv
    geew
        10
    geew  
    OP
       2014-05-13 13:02:08 +08:00
    @Sylv 谢谢 总算了解了
    geew
        11
    geew  
    OP
       2014-05-13 13:14:09 +08:00
    @Sylv 但是还有一个疑问就是, 如果你不知道输入到程序里面的字符串是unicode还是string呢? 或者你知道输入的是unicode但你不知道是用什么编码方式decode的呢?
    Sylv
        12
    Sylv  
       2014-05-14 03:57:04 +08:00 via iPhone
    @geew 不知道的话应该就只能先测试下或检测下了 好像没有什么万能的方法
    geew
        13
    geew  
    OP
       2014-05-14 09:55:19 +08:00
    @Sylv 是啊 我也只是尝试编码 然后捕捉异常
    gladuo
        14
    gladuo  
       2015-03-29 02:10:31 +08:00
    @Sylv 有些库只能接str。。。
    感觉好蛋疼
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3175 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 12:52 · PVG 20:52 · LAX 05:52 · JFK 08:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.