V2EX 首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
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
V2EX  ›  Python

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

  •  
  •   schema · 181 天前 · 2323 次点击
    这是一个创建于 181 天前的主题,其中的信息可能已经有所发展或是发生改变。

    基本情况: 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
        1
    scriptB0y   181 天前   ♥ 2
    .py 文件声明的事你脚本的编码方式,和你操作的文件没有关系。

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

    https://i.loli.net/2017/08/23/599d33d15ced5.png
        2
    qwjhb   181 天前
    'ascii' codec can't decode byte 0xe6
        3
    schema   181 天前
    @scriptB0y CentOS VPS 上运行结果为:douban.txt: UTF-8 Unicode text

    我在 Mac 上用 python3 运行 app.py 没问题,是在 CentOS VPS 用 python3.6 运行中文字符报错。
        5
    yunkchen   181 天前   ♥ 1
    f = open('douban.txt', 'r', encoding="utf-8)
    # 试一下
        6
    schema   181 天前
    @yunkchen 可以的,谢谢~
        7
    congeec   181 天前 via iPhone
    f.close()
        8
    schema   181 天前
    @congeec 请教下: 如果不关闭文件影响大不大?如果我用 with open('douban.txt', 'r', encoding="utf-8) 是不是不用关了
        9
    holajamc   181 天前
    代码执行到 with 范围以外会自己关闭文件
        10
    ekeyme   181 天前
    首先, @yunkchen 的答案 +1。

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

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

    当 python 无法正确推断 sys.stdout.encoding 时可能会报错,比如它将该 encoding 错误推断成 ascii 就会在最后对 > 127 的字节码 报错。
        15
    likuku   181 天前
    哈哈哈...最近看来开始折腾 douban 的人增加了
        16
    schema   180 天前
    @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 的,这样可以吗
        18
    NoAnyLove   180 天前   ♥ 1
    写个最简单的文件,看看你 VPS 上的 Python3 能不能执行:

    ```python
    #coding: utf-8

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

    不能的话,估计是你 Python3 安装得有问题,建议更换为 pyenv
        19
    schema   180 天前
    @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)
    ```
        20
    ekeyme   180 天前
    @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 中吧。
        21
    mingyun   179 天前
    @schema 文件失效了?
        22
    schema   179 天前
    @ekeyme 谢谢回复。

    1、locale 后返回都是 UTF-8 ;
    2、c 库我没明确升级过。VPS 较新,只装 oneinstack,不知道对 c 库有没有影响;
    3、设置并保存 ~/.bashrc 后,可以了 😄
        24
    schema   179 天前
    DigitalOcean
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   1497 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.0 · 58ms · UTC 13:26 · PVG 21:26 · LAX 05:26 · JFK 08:26
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1