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

又一次被编码问题整晕了,求解救

  •  
  •   grimpil · 2017-04-05 11:03:45 +08:00 · 3297 次点击
    这是一个创建于 2796 天前的主题,其中的信息可能已经有所发展或是发生改变。
    xshell 登录 linux 执行执行下面命令:
    python3 test.py '你好'
    这一句目前是直接手动执行的,以后计划 php 内通过 exec()来执行

    tesp.py 里面:
    str = sys.argv[1]
    print(str) //打印出来是“你好”

    if str == "你好":
    print('ok') //这一句没有输出,说明二者并不相同

    下面这两句
    print('你好'.encode('utf-8'))
    print(str.encode('utf-8'))

    第一句正常输出: // b'\xe4\xbd\xa0\xe5\xa5\xbd'
    第二句报错: UnicodeEncodeError: 'utf-8' codec can't encode character '\udce4'

    我想知道传递过来的参数,究竟发生了什么变化,明明都是“你好”,怎么会不一样
    因为后面有一步关键操作需要 str.encode('utf-8') ,怎么样才能让它不报错?
    16 条回复    2017-04-07 01:22:56 +08:00
    xiaobai987
        1
    xiaobai987  
       2017-04-05 11:24:27 +08:00
    第二句不是已经提示是 utf-8 了吗
    LokiSharp
        2
    LokiSharp  
       2017-04-05 11:26:10 +08:00
    sys.argv 传入的是 Unicode ,不需要 encode 吧?
    zhanglintc
        3
    zhanglintc  
       2017-04-05 11:28:07 +08:00 via iPhone
    会不会 str 已经是 unicode 了 所以不用 encode 了
    zhanglintc
        4
    zhanglintc  
       2017-04-05 11:28:37 +08:00 via iPhone
    写错了 str 已经不是 unicode 了 不用 encode 了
    LokiSharp
        5
    LokiSharp  
       2017-04-05 11:30:56 +08:00
    额。。。貌似说错了,应该说是 sys.argv 传入的是 UTF-8 ,不需要 encode ,然后 Python 内部声明的都是 Unicode 所以要 encode 成其他的。。。
    fds
        6
    fds  
       2017-04-05 11:32:15 +08:00
    不写 encode , python 2 3 下都正常。写 encode , python 2 失败, 3 正常。
    mac 下 iterm 运行的。不知楼主怎么回事。直接打印看看?
    yeyuexia
        7
    yeyuexia  
       2017-04-05 11:42:50 +08:00
    ✗ python --version
    Python 3.6.0

    ✗ cat test.py
    import sys

    str = sys.argv[1]
    print(str)
    print(type(str))
    if str == "你好":
    print("ok")
    print('你好'.encode('utf-8'))
    print(str.encode('utf-8'))

    ✗ python test.py '你好'
    你好
    <class 'str'>
    ok
    b'\xe4\xbd\xa0\xe5\xa5\xbd'
    b'\xe4\xbd\xa0\xe5\xa5\xbd'


    可能我用了假 python ……
    grimpil
        8
    grimpil  
    OP
       2017-04-05 11:48:21 +08:00
    @xiaobai987 即是说通过参数传递进来的 str 本身就是 utf-8 编码的字符串?
    因为我后面要用某个库里的一个函数需要对 str 执行 encode('utf-8'),里面的代码不方便改动,
    那么在此之前,我需要的把 str 变成普通的字符串,然后确保 str.encode('utf-8')能顺利执行,请问这需要怎么做
    Eleutherios
        9
    Eleutherios  
       2017-04-05 12:24:38 +08:00 via iPhone
    @grimpil 升级一下 python 版本?
    lxy42
        10
    lxy42  
       2017-04-05 12:44:22 +08:00 via Android
    unicode 才要 encode
    byte string 才要 decode
    lxy42
        11
    lxy42  
       2017-04-05 12:45:10 +08:00 via Android
    @Eleutherios 他已经是 python 3 了
    xiaobai987
        12
    xiaobai987  
       2017-04-05 13:01:18 +08:00
    @grimpil decode 试试 我也是新手
    lxy42
        13
    lxy42  
       2017-04-05 13:05:28 +08:00
    代码( python2.7 ):

    # -*- coding: utf8 -*-
    import sys

    str = sys.argv[1]
    print str #打印出来是“你好”

    if str == "你好":
    print 'ok' #打印 ok

    print '你好'.encode('utf-8') # 这行报错
    print str.encode('utf-8')

    打印信息如下:
    你好
    ok
    Traceback (most recent call last):
    File "test.py", line 10, in <module>
    print '你好'.encode('utf-8')
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

    python2 的话,如果文件编码和终端编码相同,应该会打印出 ok 的。
    python3 的话,我这边是没问题的,都是正常的,和#7 一致。
    grimpil
        14
    grimpil  
    OP
       2017-04-05 17:20:44 +08:00
    @xiaobai987
    @LokiSharp
    @zhanglintc
    @fds
    @yeyuexia
    @Eleutherios
    @lxy42

    谢谢各位,问题暂时解决了,
    str.encode('utf-8','surrogateescape')
    这样就没问题了

    不过编码解码这一块,我确实得花点功夫研究一下,
    不然每次遇到问题都要折腾好久,太痛苦了
    zhanglintc
        15
    zhanglintc  
       2017-04-05 20:46:10 +08:00 via iPhone
    @grimpil 长见识了,赶紧学习了一波 surrogateescape
    lzjun
        16
    lzjun  
       2017-04-07 01:22:56 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2831 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:11 · PVG 15:11 · LAX 23:11 · JFK 02:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.