Python 3 UnicodeEncodeError: 'ascii'编解码器无法对字符进行编码

7

我刚开始学习Python,但已经遇到了困难。
我有一个简单的脚本,只有一个命令:

#!/usr/bin/env python3
print("Příliš žluťoučký kůň úpěl ďábelské ódy.") # Text in Czech 

当我尝试运行这个脚本时:
python3 hello.py 

我收到了这个消息:
Traceback (most recent call last):
  File "hello.py", line 2, in <module>
    print("P\u0159\xedli\u0161 \u017elu\u0165ou\u010dk\xfd k\u016fn \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy.")
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-2: ordinal not in range(128)

我正在使用Kubuntu 16.04和Python 3.5.2。当我尝试这样做:export PYTHONIOENCODING=utf-8时,它可以工作,但仅在临时情况下。下次打开bash时我会得到相同的错误。
根据https://docs.python.org/3/howto/unicode.html#the-string-type,Python源代码的默认编码是UTF-8。 所以我的源文件已保存为UTF-8,Konsole也设置为UTF-8,但我仍然会遇到错误! 即使我添加了
# -*- coding: utf-8 -*-

起初它什么都不做。

另一个奇怪的事情是:当我仅使用Python而不使用Python3运行它时,它可以工作。如何在Python 2.7.12中运行并且在3.5.2中无法运行?

有没有解决这个问题的想法?谢谢。


1
听起来你的环境没有正确配置UTF-8。这就是为什么Python在打印Unicode时默认使用ascii的原因。 - Mark Tolonen
可能是写入文件时的UnicodeEncodeError的重复问题。 - Alastair McCormack
你的语言环境可能出了问题。也许你的.bashrc设置了LANG=cs_CZ.UTF-8但你还没有构建/安装捷克语环境。如果你的语言环境出现问题或丢失,Python将默认使用ASCII编码。在Python 2中它能正常运行是因为该字符串是一个字节字符串,可以直接写入终端。但在Python 3中,在写入终端时需要对字符串进行编码。 - Alastair McCormack
感谢@AlastairMcCormack指出问题所在。问题确实存在。 LANG被设置为C,这是使用ANSI的默认设置。只有少数LC_***被设置为cs_CZ.UTF-8,其他的都从LANG继承了C。我在/etc/default/locale/中添加了以下行: LANG=cs_CZ.UTF-8 LANGUAGE=cs_CZ.UTF-8 LC_ALL=cs_CZ.UTF-8 它起作用了!现在为什么我要将其写成评论而不是答案呢?现在locale的输出到处都是cs_CZ.UTF-8,除了LANG。为什么我不能设置这个变量? - user7360596
@Smety,我很高兴它起作用了。你只需要在/etc/default/locale中设置LANG。只有在想要特定的例外情况(例如使用英语错误消息)时才配置诸如LANGUAGE之类的内容。一旦设置并重新启动会话,那么每个LC_应该都是相同的。检查LANG是否在/etc/environment或个人shell文件中设置。请参阅https://help.ubuntu.com/community/Locale。 - Alastair McCormack
1个回答

11

感谢Mark TolenAlastair McCormack建议问题可能出在哪里。 问题实际上是在本地设置中。
当我运行locale时,输出为:

LANG=C
LANGUAGE=
LC_CTYPE="C"
LC_NUMERIC=cs_CZ.UTF-8
LC_TIME=cs_CZ.UTF-8
LC_COLLATE=cs_CZ.UTF-8
LC_MONETARY=cs_CZ.UTF-8
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT=cs_CZ.UTF-8
LC_IDENTIFICATION="C"
LC_ALL=

这个"C"是默认设置,使用的是ANSI字符映射表。问题就出在这里。运行locale charmap命令后,我发现它给出的是:ANSI_X3.4-1968,无法显示非英文字符。
我使用了这个Ubuntu文档站点来解决这个问题。

我在/etc/default/locale中添加了以下内容:

LANGUAGE=cs_CZ.UTF-8
LC_ALL=cs_CZ.UTF-8

然后您需要重新启动会话(注销并登录)才能应用这些设置。

现在运行 locale 将返回此输出:

LANG=C
LANGUAGE=cs
LC_CTYPE="cs_CZ.UTF-8"
LC_NUMERIC="cs_CZ.UTF-8"
LC_TIME="cs_CZ.UTF-8"
LC_COLLATE="cs_CZ.UTF-8"
LC_MONETARY="cs_CZ.UTF-8"
LC_MESSAGES="cs_CZ.UTF-8"
LC_PAPER="cs_CZ.UTF-8"
LC_NAME="cs_CZ.UTF-8"
LC_ADDRESS="cs_CZ.UTF-8"
LC_TELEPHONE="cs_CZ.UTF-8"
LC_MEASUREMENT="cs_CZ.UTF-8"
LC_IDENTIFICATION="cs_CZ.UTF-8"
LC_ALL=cs_CZ.UTF-8

并且运行locale charmap返回:

UTF-8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接