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
kojp
V2EX  ›  Python

被编码折腾得想吐了,早上六点一直折腾到现在。真想暴粗口~~~。

  •  
  •   kojp · 2012-05-08 08:13:53 +08:00 · 6649 次点击
    这是一个创建于 4586 天前的主题,其中的信息可能已经有所发展或是发生改变。
    真心求助!

    一直都小心翼翼地用unicode。现在写到数据库里的是unicode

    取出来以后还是unicode

    u'\u8c37\u6b4c\u4e91\u5b58\u50a8'

    直接在终端里面输出,
    print u'\u8c37\u6b4c\u4e91\u5b58\u50a8'

    谷歌云存储

    可以正常显示中文。

    在程序里面输出,就是 u'\u8c37\u6b4c\u4e91\u5b58\u50a8'~~~~

    啊!!!尼妹的!编码~~~~
    37 条回复    1970-01-01 08:00:00 +08:00
    Livid
        1
    Livid  
    MOD
       2012-05-08 08:22:41 +08:00
    Python?

    Post full code to gist?
    likai
        2
    likai  
       2012-05-08 08:24:08 +08:00
    源文件的编码是不是UNICODE
    kojp
        3
    kojp  
    OP
       2012-05-08 08:41:53 +08:00
    @likai
    为了杜绝这个情况 , 已经直接在 linux平台编码了 . . .也不排除这种极端的可能性 .----- print sys.stdin已经是 utf8了
    @Livid

    Thanks, 现在在路上 ,到办公室了再上上传 .
    Livid
        4
    Livid  
    MOD
       2012-05-08 08:48:37 +08:00
    @kojp 期待。

    我每次遇到这类编码问题都很有兴趣解决。

    移动到 /go/python 了。
    kojp
        5
    kojp  
    OP
       2012-05-08 10:29:57 +08:00
    chainchan
        6
    chainchan  
       2012-05-08 10:37:30 +08:00
    # -*- coding: utf-8 -*-
    import sys
    type = sys.getfilesystemencoding()
    print content.decode('utf-8').encode(type)
    kojp
        7
    kojp  
    OP
       2012-05-08 10:39:08 +08:00
    @chainchan 呃,跟数据库取出来的东西有关吧。

    各种decode,encode,codec,chardet都试过了~~ :-(
    clowwindy
        8
    clowwindy  
       2012-05-08 10:58:13 +08:00   ❤️ 1
    Unicode 是一个 21 位的字符空间。它不是一种编码。要输入输出,必须进行解/编码。

    UTF-8 是对这个 21 位的字符空间到 8 位的字节形式的一种编码。

    在程序内部,可以使用 Unicode。一旦输出,必须编码成字节。如果你自己不做这个转换,print 的时候 Python 会用默认编码给你编码。有时这个默认的编码不是 UTF-8,就会出问题。所以最好自己显式的进行编码。
    binux
        9
    binux  
       2012-05-08 11:01:04 +08:00
    @kojp 没有看到“在程序里面输出,就是 u'\u8c37\u6b4c\u4e91\u5b58\u50a8'” 的现象啊?
    chainchan
        10
    chainchan  
       2012-05-08 11:05:07 +08:00
    @kojp 你建立数据库时候是用什么编码?

    你可以看看这个或许能解决你的问题,我不太清清楚你具体的工作环境
    http://mobile2008.blogbus.com/logs/28531317.html
    wynemo
        11
    wynemo  
       2012-05-08 11:49:59 +08:00
    https://github.com/r00te4/tips/blob/master/sendmail/testsendmail.py

    看了下 比较混乱 这些repr gbk gb2312是用来干嘛的啊

    都用utf-8的str吧

    不管那些注释了 你现在这个函数getMailContents 返回的unicode 通过encode('utf-8') 变成str 再用到sendEmail 应该是没问题的
    wynemo
        12
    wynemo  
       2012-05-08 12:08:10 +08:00
    测试了一下 正常

    http://gist.github.com/2632474
    kojp
        13
    kojp  
    OP
       2012-05-08 12:32:53 +08:00
    @wynemo 问题是,我取出来的时候,他就直接是STR了。

    我再给他转成unicode, 再encode成utf-8

    就不行了~~
    libei
        14
    libei  
       2012-05-08 12:35:48 +08:00
    再复习复习吧。
    中文编码漫谈:http://news.congci.com/news/china-encoding-mantan
    9hills
        15
    9hills  
       2012-05-08 12:37:25 +08:00
    Python的中文处理方面这个thread基本都讲完了。。建议看看(需cross wall)

    https://groups.google.com/d/topic/cn.bbs.comp.lang.python/8KO7YrgUVXM/discussion

    说回你的程序:你的程序的关键部分是:

    htmltext=u"\u8c37\u6b4c\u4e91\u5b58\u50a8"
    然后再sendEmail(htmltext).

    你要知道
    a="中文"

    b=u'\u4e2d\u6587'
    是不一样的,其中b=a.decode("utf-8")
    显然sendmail不能接受unicode的字符串做参数,必须是utf-8的。。。
    kojp
        16
    kojp  
    OP
       2012-05-08 12:52:32 +08:00
    @9hills

    htmltext=u"\u8c37\u6b4c\u4e91\u5b58\u50a8" 这样是对的。
    isinstance(htmltest,unicode) 的结果为true
    print 出来,不乱码。

    但我从数据库里读出来的 isinstance(htmltest,unicode) 的结果为false
    我想问题就在这~~~

    但是还是没办法解决 :-|
    kojp
        17
    kojp  
    OP
       2012-05-08 12:56:27 +08:00
    @chainchan @9hills @chainchan

    你们给的链接,我一个一个看吧。(虽然大多数,以前都看过, 上次也是解决一个编码的问题,但跟数据库无关)

    谢谢。

    有人能帮我仔细看一下我从数据库里查询信息这块的编码会不会有误?(数据库是utf-8 编码)

    PS: 我有点怀疑,我肯定是掉进一个不知名的坑爹“坑”里了,比如说逻辑错误,或者其它非编码错误。
    wynemo
        18
    wynemo  
       2012-05-08 13:07:05 +08:00   ❤️ 1
    @kojp 大概就是这句吧 repr(mailInfo[3]).encode("utf-8")

    正确的做法是rmailInfo[3].encode("utf-8")

    >>> print repr(u'中文毫无压力abcはじめまして').encode("utf-8").decode('utf-8')
    u'\u4e2d\u6587\u6beb\u65e0\u538b\u529babc\u306f\u3058\u3081\u307e\u3057\u3066'
    >>> print u'中文毫无压力abcはじめまして'.encode("utf-8").decode('utf-8')
    中文毫无压力abcはじめまして

    用repr当然还原不了了。。。。
    kojp
        19
    kojp  
    OP
       2012-05-08 13:12:06 +08:00
    @wynemo 你是对的! 现在能看到中文了。我看一下到邮箱里面是否乱码~~~谢谢!!!!(其实repr那个,我也就是百种百度GOOGLE各种尝试的~~没有真实依据)
    kojp
        20
    kojp  
    OP
       2012-05-08 13:31:49 +08:00
    恭喜一下自己,有“进步”了。
    终于脱离了滥谷的 u'\u4e2d\u6587\u6beb\u65e0\u538b\u529babc\u306f\u3058\u3081\

    已经进化到
    '\xe5\x91\xa8\xe6\x9c\xab\xe8\xa6\x81\xe9\x97\xbb\xe5\x9b\x9e\xe9\xa1\xbe
    了。哈哈。
    magicshui
        21
    magicshui  
       2012-05-08 13:36:08 +08:00
    我真被编码问题折腾吐过~
    9hills
        22
    9hills  
       2012-05-08 13:41:08 +08:00
    @kojp
    htmltext=u"\u8c37\u6b4c\u4e91\u5b58\u50a8"
    这个当然是unicode。。u开头的都是unicode,但是它不是utf-8啊

    unicode是直接可以print的,utf-8也是直接可以在UTF-8的终端中print的。。。但是不能混

    你这句
    msgText.set_charset("utf-8")
    msgText = MIMEText(htmlText, 'html', 'utf-8')
    明明htmlText是unicode,但是你又把它指定为utf-8。。岂不是会混乱
    kojp
        23
    kojp  
    OP
       2012-05-08 13:42:29 +08:00
    @wynemo

    伸手党来了,貌似只能靠你拯救了。哥们~~

    按你的说法,我已经可以成功print 出中文了。

    但是,当我把这串unicode传到sendmail里面去,提示要字符串。(返回的是list0
    我乖乖地str(htmltext)然后,再print 就成'\xe5\x91\xa8\xe6\'这个样子了。不用str用unicode更糟糕,字节都给分散了~~
    9hills
        24
    9hills  
       2012-05-08 13:46:30 +08:00
    @kojp replay to #20
    你这一大串是utf-8。。。
    打开python,试试下面这个(Linux UTF-8 locale)

    >>> a="中文" #a是utf-8的字符串
    >>> a
    '\xe4\xb8\xad\xe6\x96\x87'
    >>>print a #打印a
    中文
    >>> au=a.decode("utf8") #把a变成unicode
    >>> au
    u'\u4e2d\u6587'
    >>> print au
    中文
    >>> au.encode("utf8") #又把unicode的au变成utf8
    '\xe4\xb8\xad\xe6\x96\x87'
    9hills
        25
    9hills  
       2012-05-08 13:47:41 +08:00
    @kojp #23 本来就是字符串,不要用str,repr来转编码。。。
    用 htmltext.encode("utf8") 转
    kojp
        26
    kojp  
    OP
       2012-05-08 13:50:06 +08:00
    结贴!

    谢谢各位!
    kojp
        27
    kojp  
    OP
       2012-05-08 13:52:47 +08:00
    不光吐血,感触N多。。。很多都是因为基础知识不够扎实-------回去恶补!
    这两天要写一篇总结同来。

    再次谢谢各位v2exer! (抱拳!)
    kojp
        28
    kojp  
    OP
       2012-05-08 13:55:25 +08:00
    """我乖乖地str(htmltext)然后,再print 就成'\xe5\x91\xa8\xe6\'这个样子了。不用str用unicode更糟糕,字节都给分散了~~"""


    关于这个问题,我是这样解决的,(估计可能有其它的函数或者方法,但我没找见怪不怪

    我直接循环了一下返回的unicode列表。然后字符串拼接一下。然后传给sendmail.

    这个办法貌似土到家了,但暂时也只能这样。记得上次有个问题也是这样解决的。总的来说,还是对list和str的内部结构了解不够透彻。
    binux
        29
    binux  
       2012-05-08 14:07:28 +08:00
    完全不明白说的是什么。。
    reus
        30
    reus  
       2012-05-08 14:11:09 +08:00
    一个unicode列表转换成str这样就行了啊
    ''.join(s.encode('utf8') for s in l)

    说到底就是你不知道encode, decode这两个方法,编码转换根本不需要用到str和unicode两个函数的
    reus
        31
    reus  
       2012-05-08 14:21:37 +08:00
    你的程序最下面那个htmlText的类型是unicode,也就是unicode字符串,如果要转换成str类型的字符串,直接htmlText.encode('utf8')就可以了
    benzhe
        32
    benzhe  
       2012-05-08 14:41:43 +08:00
    貌似 python 的编码问题的确会难处理一些,当初只是弄一个文件上传,文件名的编码也是折腾了很久。php javascript 怎么弄都没这么麻烦...
    csx163
        33
    csx163  
       2012-05-08 14:58:26 +08:00
    @Livid 每次遇到这种情况都tm的想死啊
    reus
        34
    reus  
       2012-05-08 15:08:13 +08:00
    php也一样要用到iconv处理编码,py不比其他语言更难处理,是使用者对unicode不理解而已
    clowwindy
        35
    clowwindy  
       2012-05-08 19:57:16 +08:00
    理解什么是 Unicode,什么是编码,比理解怎么在语言里用这些东西更重要一些。
    kojp
        36
    kojp  
    OP
       2012-05-08 20:03:32 +08:00
    @reus
    encode,decode的字面意思,是知道的。但很多时候,感觉他们就是不听话~~~~
    iconv感觉半个小时就能解决吧,而且绝对不至于折腾到想吐~~~
    @clowwindy

    有道理,经历此事件后,需要各种恶补。
    reus
        37
    reus  
       2012-05-08 20:12:46 +08:00
    @kojp php用iconv就相当于没有unicode类型,全部是str类型。py多了个unicode类型,可以直接len而不是像php一样要mb_strlen,更方便了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5555 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 06:48 · PVG 14:48 · LAX 22:48 · JFK 01:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.