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

Python3 下读取 .txt 文件中文乱码问题

  •  
  •   schema · 2017-08-23 15:18:39 +08:00 · 9749 次点击
    这是一个创建于 2436 天前的主题,其中的信息可能已经有所发展或是发生改变。

    基本情况: Vultr $2.5/year, CentOS 7, 安装的是 Python3.6。

    @app.route("/douban", methods=['GET'])
    def doubanFM():
        f = open('douban.txt', 'r')
        txt = f.read()
        lines = txt.split('#\n')
        lines = lines[:-1]
        return random.choice(lines)
    

    用 Python3.6 运行上面的代码,出现错误。其中,douban.txt 文件中大都为中文字符,.py 文件开头加了 #coding:utf-8。主要错误代码如下:

    ...
    ...
    File "/usr/lib64/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
        rv = self.dispatch_request()
      File "/usr/lib64/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "/root/weather/app.py", line 32, in DoubanFM
        txt = f.read()
      File "/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
        return codecs.ascii_decode(input, self.errors)[0]
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)
    
    

    后来没办法换用 CentOS 自带的 Python2 运行,没错误,能正常输出中文。但我很想知道为啥用 Python3.6 来运行就不行,求相应解决办法。

    24 条回复    2017-08-25 09:36:22 +08:00
    scriptB0y
        1
    scriptB0y  
       2017-08-23 15:50:49 +08:00   ❤️ 2
    .py 文件声明的事你脚本的编码方式,和你操作的文件没有关系。

    file douban.txt 看一下编码方式。

    https://i.loli.net/2017/08/23/599d33d15ced5.png
    qwjhb
        2
    qwjhb  
       2017-08-23 15:53:18 +08:00
    'ascii' codec can't decode byte 0xe6
    schema
        3
    schema  
    OP
       2017-08-23 16:11:08 +08:00
    @scriptB0y CentOS VPS 上运行结果为:douban.txt: UTF-8 Unicode text

    我在 Mac 上用 python3 运行 app.py 没问题,是在 CentOS VPS 用 python3.6 运行中文字符报错。
    schema
        4
    schema  
    OP
       2017-08-23 16:16:08 +08:00
    yunkchen
        5
    yunkchen  
       2017-08-23 16:23:01 +08:00   ❤️ 1
    f = open('douban.txt', 'r', encoding="utf-8)
    # 试一下
    schema
        6
    schema  
    OP
       2017-08-23 16:36:42 +08:00
    @yunkchen 可以的,谢谢~
    congeec
        7
    congeec  
       2017-08-23 16:46:01 +08:00 via iPhone
    f.close()
    schema
        8
    schema  
    OP
       2017-08-23 16:56:24 +08:00
    @congeec 请教下: 如果不关闭文件影响大不大?如果我用 with open('douban.txt', 'r', encoding="utf-8) 是不是不用关了
    holajamc
        9
    holajamc  
       2017-08-23 16:59:15 +08:00
    代码执行到 with 范围以外会自己关闭文件
    ekeyme
        10
    ekeyme  
       2017-08-23 17:09:37 +08:00
    首先, @yunkchen 的答案 +1。

    感觉跟我之前遇到的问题类似,我估计你 用 open('douban.txt', 'r', encoding="utf-8) 之后,然后 read() 出来数据;我估计你打印(print)的时候也会报错。

    你 3.6 自己编译安装的吧? 安装后有升级过 系统的 C 库么?
    rocksolid
        11
    rocksolid  
       2017-08-23 17:14:41 +08:00
    @schema with 会自动关
    twistoy
        12
    twistoy  
       2017-08-23 17:15:16 +08:00
    @ekeyme print 的时候报不报错取决于终端的使用的编码吧,和代码就没啥关系了吧。
    yunkchen
        13
    yunkchen  
       2017-08-23 17:15:17 +08:00
    @schema 尽量都用 with open... as ...来打开文件。
    ekeyme
        14
    ekeyme  
       2017-08-23 17:26:09 +08:00
    @twistoy 我所指的报错是 python raise Exception。系统遇到打印不出来的字符是会用[乱码]形式展现不会报错。

    当 python 无法正确推断 sys.stdout.encoding 时可能会报错,比如它将该 encoding 错误推断成 ascii 就会在最后对 > 127 的字节码 报错。
    likuku
        15
    likuku  
       2017-08-23 18:06:47 +08:00
    哈哈哈...最近看来开始折腾 douban 的人增加了
    schema
        16
    schema  
    OP
       2017-08-23 22:14:06 +08:00
    @ekeyme 我那时是按照 DO 上的这篇 **[文章]( https://www.digitalocean.com/community/tutorials/how-to-install-python-3-and-set-up-a-local-programming-environment-on-centos-7)** 在 CentOS 上安装 Python3.6 的,这样可以吗
    NoAnyLove
        18
    NoAnyLove  
       2017-08-23 22:39:52 +08:00   ❤️ 1
    写个最简单的文件,看看你 VPS 上的 Python3 能不能执行:

    ```python
    #coding: utf-8

    # 中文注释
    print("中文哟")
    ```

    不能的话,估计是你 Python3 安装得有问题,建议更换为 pyenv
    schema
        19
    schema  
    OP
       2017-08-23 23:44:20 +08:00
    @NoAnyLove 运行后,确实出错了。我明天重装看看~~

    ```
    Traceback (most recent call last):
    File "zz.py", line 4, in <module>
    print("\u4e2d\u6587\u54df")
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
    ```
    ekeyme
        20
    ekeyme  
       2017-08-24 15:25:09 +08:00
    @schema 可能跟你 python 安装得方式无关。

    也有可能是的 VPS 系统语言设置得不对。用 `locale` 命令查看下,本地化得设置, 确认是否为 UTF-8(特别是 LC_CTYPE=xxx.UTF-8)。

    如果你自己升级过 c 库,就很有可能出问题。这时你可能直接设置不回来 `LC_CTYPE=xxx.UTF-8`, 可以 参照 https://my.oschina.net/VASKS/blog/659236 去 `yum reinstall glibc-common` 看看。这个问题我也 hold 不住,各种坑要详细一步步解才行。

    最后还有一个简便得解决方案就是,设定 python 的 encoding 的环境变量(PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.)。

    e.g.

    `export PYTHONIOENCODING=utf-8`

    或者 你将此变量保存到 ~/.bashrc 中吧。
    mingyun
        21
    mingyun  
       2017-08-24 21:49:09 +08:00
    @schema 文件失效了?
    schema
        22
    schema  
    OP
       2017-08-25 09:31:44 +08:00
    @ekeyme 谢谢回复。

    1、locale 后返回都是 UTF-8 ;
    2、c 库我没明确升级过。VPS 较新,只装 oneinstack,不知道对 c 库有没有影响;
    3、设置并保存 ~/.bashrc 后,可以了 😄
    schema
        23
    schema  
    OP
       2017-08-25 09:33:21 +08:00
    schema
        24
    schema  
    OP
       2017-08-25 09:36:22 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1324 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 23:38 · PVG 07:38 · LAX 16:38 · JFK 19:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.