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

Python 一个关于字符编码的诡异问题(Non-UTF-8 code starting with '\xe5')

  •  
  •   q3011893 · 2019-12-02 21:13:16 +08:00 · 5864 次点击
    这是一个创建于 1826 天前的主题,其中的信息可能已经有所发展或是发生改变。

    先上代码 1:

    s = """ 安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大 """
    print(s)
    

    执行代码 1,会报错:SyntaxError: Non-UTF-8 code starting with '\xe5' in file

    再上代码 2:

    s = """ 师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大安师大 """
    print(s)
    

    代码 2 就是把代码 1 的 s 字符串变量里,随便删一个字,比如删开头的,然后就可以成功打印结果了。

    靠!!!这是什么鬼???就差一个字符就能有这么大的变化?

    当然解决代码 1 还有种办法,就是文件头部加# -*- coding: utf-8 -*-,但是为什么呢?? python3 不就是默认 utf-8 的吗?


    执行环境:

    1、macos

    2、vscode / sublime text 3 都不可以

    3、python3.7 ( anaconda 的和自己编译装的 python 3.7 亲测都不行) [但是网页版的这个 “python 3 在线执行” 却可以 https://c.runoob.com/compile/9 ]

    14 条回复    2019-12-05 15:37:48 +08:00
    ma6254
        1
    ma6254  
       2019-12-02 21:23:45 +08:00
    1.本地源文件什么格式?
    2.这串字符里面是否有不可见字符
    imn1
        2
    imn1  
       2019-12-02 21:25:45 +08:00
    SyntaxError
    这个极可能是.py 文件保存的格式有问题
    我估计是 bom 的问题
    Jirajine
        3
    Jirajine  
       2019-12-02 21:27:03 +08:00
    试了一下,vscode 里执行默认有这么一行预处理${env:PYTHONIOENCODING}='UTF-8'; 所以并没有问题,直接在 powershell 终端执行复现,使用 wsl 里的 python 正常。然后删字依旧报错并不管用。
    Trim21
        4
    Trim21  
       2019-12-02 21:44:50 +08:00
    @ma6254 #1 没有不可见字符...
    lysS
        5
    lysS  
       2019-12-02 22:00:17 +08:00
    好奇你为什么会写怎么一串东西。。。
    JCZ2MkKb5S8ZX9pq
        6
    JCZ2MkKb5S8ZX9pq  
       2019-12-02 22:28:42 +08:00
    我是 sublime 出现这个情况需要满足多个条件。
    我头部声明一般都保留,需要去掉声明才会报错。
    同时我如果用的一个自定义 build,加了-um,也不会出现这个错误。

    感觉开头的这个声明,在处理 utf8 的时候,直接就处理了逃逸,把\xe5 给解决掉了。
    找了一下,好像依据是这个。
    我理解就是不加这行话,py3 把文件当 utf8 来读,读到意外的字符就报错了。
    加了这段话之后,多做了一步转义加成,于是把违禁字符先给解决了,然后才开始运行。

    Handling of escape sequences should continue to work as it does now, but with all possible source code encodings, that is standard string literals (both 8-bit and Unicode) are subject to escape sequence expansion while raw string literals only expand a very small subset of escape sequences.

    [PEP 263 -- Defining Python Source Code Encodings | Python.org]( https://www.python.org/dev/peps/pep-0263/)
    JCZ2MkKb5S8ZX9pq
        7
    JCZ2MkKb5S8ZX9pq  
       2019-12-02 22:31:05 +08:00
    我是直接写了个 python 的 snippet,自动模板。
    开头加两行
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-

    之前也没多想,就放着呗。
    ggicci
        8
    ggicci  
       2019-12-02 23:45:32 +08:00
    一没说操作系统,二没说文件编码,查 bug 全靠猜吗?佛的了。。。
    wangyzj
        9
    wangyzj  
       2019-12-03 01:05:25 +08:00
    命令行直接 python 测试你的两个代码都没问题
    所以应该不是代码问题
    ClericPy
        10
    ClericPy  
       2019-12-03 09:12:59 +08:00
    在 Windows 上用藏文试过, 除了 shebang 加 coding, 没有任何其他办法, 死了这条心吧
    j0hnj
        11
    j0hnj  
       2019-12-03 11:56:06 +08:00
    windows 下命令行测试,两个都没问题


    @ggicci #8 人家说了操作系统的
    j0hnj
        12
    j0hnj  
       2019-12-03 12:01:08 +08:00
    从楼主的描述来看,我严重怀疑漏洞搞错了 python 版本,楼主执行的应该是 python2
    datou
        13
    datou  
       2019-12-03 15:28:24 +08:00
    win10 下 py36,py37,py38 都没问题
    lolizeppelin
        14
    lolizeppelin  
       2019-12-05 15:37:48 +08:00
    WINHEX 用二进制打开文件对比你就知道什么问题了

    瞎猜个什么劲
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   919 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:26 · PVG 06:26 · LAX 14:26 · JFK 17:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.