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

问一个让我很困扰的编码问题。

  •  
  •   SimbaPeng · 2018-03-01 11:14:59 +08:00 · 1843 次点击
    这是一个创建于 2489 天前的主题,其中的信息可能已经有所发展或是发生改变。
    Py3.6

    >>> r'\u4e2d'.encode('unicode_escape')
    b'\\\\u4e2d'
    >>> b'\\\\u4e2d'.decode('unicode_escape')
    '\\u4e2d'
    >>> b'\u005c\u0075\u0034\u0065\u0032\u0064'.decode('unicode_escape')
    '\\u4e2d'
    >>> b'\u005c\u0075\u0034\u0065\u0032\u0064'.decode('unicode_escape') == b'\\\\u4e2d'.decode('unicode_escape')
    True
    >>> b'\u005c\u0075\u0034\u0065\u0032\u0064' == b'\\\\u4e2d'
    False


    r'\u4e2d' 的 unicode 编码应该是 b'\u005c\u0075\u0034\u0065\u0032\u0064'这个阿,为什么 encode('unicode_escape')出来的是 b'\\\\u4e2d'这个?

    而且 b'\\\\u4e2d'和 b'\u005c\u0075\u0034\u0065\u0032\u0064' 都可以解码出来 r'\u4e2d',这是为什么?
    2 条回复    2018-03-01 11:47:51 +08:00
    imn1
        1
    imn1  
       2018-03-01 11:46:49 +08:00
    你比较一下这个
    r'\u4e2d'.encode('raw_unicode_escape')

    然后再看看文档,搞清楚 unicode_escape 的行为是什么
    scriptB0y
        2
    scriptB0y  
       2018-03-01 11:47:51 +08:00   ❤️ 1
    有意思,我昨天刚纠结了这个问题。

    unicode-escape 先 encode()然后按照字面 escape 一次。

    In [32]: "中国".encode('unicode-escape')
    Out[32]: b'\\u4e2d\\u56fd'

    In [33]: "中国".encode()
    Out[33]: b'\xe4\xb8\xad\xe5\x9b\xbd'

    In [34]: len(b'\\u4e2d\\u56fd')
    Out[34]: 12

    所以你的 r'\u4e2d'.encode('unicode-escape') 实际上是这样:

    In [36]: r'\u4e2b'.encode()
    Out[36]: b'\\u4e2b'

    先 encode()的到了 b'\\u4e2b' , 这个时候得到 6 个 byte, \ u 4 e 2 b,注意只有一个 \ ,前面一个是转义用的。

    再按照字面意思就是 \ \ u 4 e 2 b 一共 7 个字符对吧。前面转义的 \ 也被按照字面解释成了一个 \ 。

    第一个问题回答完毕。
    -----------------------------------


    解码问题:

    解码的时候,unicode-escape 可能将多个 byte 解释成一个,例如

    对于 b'\\\\u4e2d' escape 这一步变成 \\u4e2d,从 7 个字符变成了 6 个。

    对于 b'\u005c\u0075\u0034\u0065\u0032\u0064' , 从 36 个变成了 6 个。

    再啰嗦一点,前者, 第一个 \ 转义了第二个 \ 结束了。 后者第一个 \ 转义了 u 继续向后直到 \u005c 被解释成 1 个字符。

    所以两者 decode('unicode-escape')的结果是一样的。

    昨天的帖子: https://www.kawabangga.com/posts/2767
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1175 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:13 · PVG 02:13 · LAX 10:13 · JFK 13:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.