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

2017-08-23 15:18:39 +08:00
 schema

基本情况: 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 来运行就不行,求相应解决办法。

9927 次点击
所在节点    Python
24 条回复
scriptB0y
2017-08-23 15:50:49 +08:00
.py 文件声明的事你脚本的编码方式,和你操作的文件没有关系。

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

https://i.loli.net/2017/08/23/599d33d15ced5.png
qwjhb
2017-08-23 15:53:18 +08:00
'ascii' codec can't decode byte 0xe6
schema
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
2017-08-23 16:16:08 +08:00
yunkchen
2017-08-23 16:23:01 +08:00
f = open('douban.txt', 'r', encoding="utf-8)
# 试一下
schema
2017-08-23 16:36:42 +08:00
@yunkchen 可以的,谢谢~
congeec
2017-08-23 16:46:01 +08:00
f.close()
schema
2017-08-23 16:56:24 +08:00
@congeec 请教下: 如果不关闭文件影响大不大?如果我用 with open('douban.txt', 'r', encoding="utf-8) 是不是不用关了
holajamc
2017-08-23 16:59:15 +08:00
代码执行到 with 范围以外会自己关闭文件
ekeyme
2017-08-23 17:09:37 +08:00
首先, @yunkchen 的答案 +1。

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

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

当 python 无法正确推断 sys.stdout.encoding 时可能会报错,比如它将该 encoding 错误推断成 ascii 就会在最后对 > 127 的字节码 报错。
likuku
2017-08-23 18:06:47 +08:00
哈哈哈...最近看来开始折腾 douban 的人增加了
schema
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 的,这样可以吗
schema
2017-08-23 22:14:37 +08:00
NoAnyLove
2017-08-23 22:39:52 +08:00
写个最简单的文件,看看你 VPS 上的 Python3 能不能执行:

```python
#coding: utf-8

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

不能的话,估计是你 Python3 安装得有问题,建议更换为 pyenv
schema
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
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 中吧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/385184

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX