python - UnicodeEncodeError : 'ascii' codec can't encode character in position 0: ordinal not in range(128)

标签 python encoding python-3.2

我正在编写一个使用剪刀字符 (9986 - ✂) 的 Python 脚本,我正在尝试将我的代码移植到 Mac,但我遇到了这个错误。

从 IDLE (Python 3.2.5 - OS X 10.4.11 iBook G4 PPC) 运行时,剪刀字符显示正常,并且代码在 Ubuntu 13.10 上运行良好,但是当我尝试在终端中运行它时,我得到了此错误/回溯:

Traceback (most recent call last):
  File "snippets-convert.py", line 352, in <module>
    main()
  File "snippets-convert.py", line 41, in main
    menu()
  File "snippets-convert.py", line 47, in menu
    print ("|\t ",snipper.decode(),"PySnipt'd",snipper.decode(),"\t|")
UnicodeEncodeError: 'ascii' codec can't encode character '\u2702' in position 0: ordinal not in range(128)

以及给我带来问题的代码:

print ("|\t ",chr(9986),"PySnipt'd",chr(9986),"\t|")

这不是表示终端没有显示该字符的能力吗?我知道这是一个旧系统,但它是目前我必须使用的唯一系统。操作系统的年龄是否会干扰程序?

我已经阅读了这些问题:

是什么导致了这个错误?是系统/操作系统的时代,Python的版本,还是一些编程错误?

编辑: 这个错误稍后会出现这个重复的问题(只是想我会添加它,因为它在同一个程序中并且是相同的错误):

Traceback (most recent call last):
  File "snippets-convert.py", line 353, in <module>
    main()
  File "snippets-convert.py", line 41, in main
    menu()
  File "snippets-convert.py", line 75, in menu
    main()
  File "snippets-convert.py", line 41, in main
    menu()
  File "snippets-convert.py", line 62, in menu
    search()
  File "snippets-convert.py", line 229, in search
    print_results(search_returned)      # Print the results for the user
  File "snippets-convert.py", line 287, in print_results
    getPath(toRead)                                             # Get the path for the snippet
  File "snippets-convert.py", line 324, in getPath
    snipXMLParse(path)
  File "snippets-convert.py", line 344, in snipXMLParse
    print (chr(164),child.text)
UnicodeEncodeError: 'ascii' codec can't encode character '\xa4' in position 0: ordinal not in range(128)

编辑:

我进入了终端字符设置,它确实支持该字符(如您在此屏幕截图中所见:

enter image description here

当我将它插入终端时,它会打印出:\342\234\202,当我按下 Enter 时,我得到:-bash: ✂ : 找不到命令

EDIT以@J.F. 的身份运行命令。塞巴斯蒂安问:

python3 test-io-encoding.py:

PYTHONIOENCODING:       None
locale(False):  US-ASCII
device(stdout): US-ASCII
stdout.encoding:        US-ASCII
device(stderr): US-ASCII
stderr.encoding:        US-ASCII
device(stdin):  US-ASCII
stdin.encoding: US-ASCII
locale(False):  US-ASCII
locale(True):   US-ASCII

python3 -S test-io-encoding.py:

PYTHONIOENCODING:       None
locale(False):  US-ASCII
device(stdout): US-ASCII
stdout.encoding:        US-ASCII
device(stderr): US-ASCII
stderr.encoding:        US-ASCII
device(stdin):  US-ASCII
stdin.encoding: US-ASCII
locale(False):  US-ASCII
locale(True):   US-ASCII

编辑尝试了@PauloBu 提供的“hackerish”解决方案:

如您所见,这导致了一个(耶!)剪刀,但我现在遇到了一个新错误。回溯/错误:

+-=============================-+
✂Traceback (most recent call last):
  File "snippets-convert.py", line 357, in <module>
    main()
  File "snippets-convert.py", line 44, in main
    menu()
  File "snippets-convert.py", line 52, in menu
    print("|\t "+sys.stdout.buffer.write(chr(9986).encode('UTF-8'))+" PySnipt'd "+ sys.stdout.buffer.write(chr(9986).encode('UTF-8'))+" \t|")
TypeError: Can't convert 'int' object to str implicitly

编辑添加了@PauloBu 的修复结果:

+-=============================-+
|
✂ PySnipt'd 
✂       |
+-=============================-+

编辑:

他的修复:

+-=============================-+
✂✂|       PySnipt'd     |
+-=============================-+

最佳答案

当 Python 打印和输出时,它会自动将其编码到目标介质。如果是文件,默认使用 UTF-8,每个人都会很高兴,但如果是终端,Python 会找出终端使用的编码,并尝试使用该编码对输出进行编码。

这意味着如果您的终端使用 ascii 作为编码,Python 正在尝试将 scissor char 编码为 ascii。当然,ascii 不支持,所以会出现 Unicode 解码错误。

这就是为什么您总是必须明确编码您的输出。显式优于隐式 还记得吗?要修复您的代码,您可以这样做:

import sys
sys.stdout.buffer.write(chr(9986).encode('utf8'))

这似乎有点骇人听闻。您还可以在执行脚本之前设置 PYTHONIOENCODING=utf-8 。我对这两种解决方案都感到不舒服。可能您的控制台不支持 utf-8 并且您会看到乱码。但是您的程序会正常运行。

如果您确实需要在控制台上显示正确的输出,我强烈建议您将控制台设置为使用另一种编码,即支持 scissor 字符的编码。 (也许是 utf-8)。在 Linux 上,这可以通过执行以下操作来实现:export lang=UTF_8。在 Windows 上,您可以使用 chcp 更改控制台的代码页。只需弄清楚如何在您的文件中设置 utf8,恕我直言,这将是最好的解决方案。


您不能混合使用 printsys.stdout.write 因为它们基本相同。关于您的代码,黑客的方式是这样的:

sys.stdout.buffer.write(("|\t "+ chr(9986) +" PySnipt'd " + chr(9986)+" \t|").encode('utf8'))

我建议您阅读文档以了解使用 print 函数和 sys.stdout 的幕后情况:http://docs.python.org/3/library/sys.html#sys.stdin

希望这会有所帮助!

关于python - UnicodeEncodeError : 'ascii' codec can't encode character in position 0: ordinal not in range(128),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20923663/

相关文章:

Python - 从列表的中间开始迭代,然后检查任一侧

xml - 修复 VBA 中的 XML 编码

python - 如何从python3中的单行输入读取整数数组

python - Python3.2如何安装matplotlib

python - BeautifulSoup Python 3 兼容性

python - 如何忽略 nose2 中的文件或目录?

python - 如何加快读取多个文件并将数据放入数据框中?

php - 错误的utf8编码导出Mysql数据库

c# - 用小写字母进行 Python URL 编码?

Python3.2 : Installing MySQL-python fails with error "No module named ConfigParser"