UnicodeEncodeError: 'ascii' 编解码器无法对位置 0 中的字符进行编码:序号不在范围内 (128) [英] UnicodeEncodeError: 'ascii' codec can't encode character in position 0: ordinal not in range(128)

查看:33
本文介绍了UnicodeEncodeError: 'ascii' 编解码器无法对位置 0 中的字符进行编码:序号不在范围内 (128)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

回溯(最近一次调用最后一次): 中的文件snippets-convert.py",第 352 行主要的()文件snippets-convert.py",第 41 行,在 main菜单()文件snippets-convert.py",第 47 行,在菜单中打印 ("|	 ",snipper.decode(),"PySnipt'd",snipper.decode(),"	|")UnicodeEncodeError: 'ascii' 编解码器无法对位置 0 中的字符 'u2702' 进行编码:序号不在范围内 (128)

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

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

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

我已经阅读了这些问题:

是什么导致了这个错误?是系统/操作系统的年龄、Python 的版本还是某些编程错误?

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

回溯(最近一次调用最后一次): 中的文件snippets-convert.py",第 353 行主要的()文件snippets-convert.py",第 41 行,在 main菜单()文件snippets-convert.py",第 75 行,在菜单中主要的()文件snippets-convert.py",第 41 行,在 main菜单()文件snippets-convert.py",第 62 行,在菜单中搜索()文件snippets-convert.py",第 229 行,在搜索中print_results(search_returned) # 为用户打印结果文件snippets-convert.py",第 287 行,在 print_results 中getPath(toRead) # 获取片段的路径文件snippets-convert.py",第 324 行,在 getPath 中snipXMLParse(路径)文件snippets-convert.py",第 344 行,在 snipXMLParse 中打印(chr(164),child.text)UnicodeEncodeError: 'ascii' 编解码器无法对位置 0 中的字符 'xa4' 进行编码:序号不在范围内 (128)

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

当我将它插入终端时,它会打印出:342234202 并且当我按下 Enter 我得到这个:-bash: ✂: 命令未找到

EDIT Ran 命令为@J.F.塞巴斯蒂安问道:

python3 test-io-encoding.py:

Python 编码:无语言环境(假):US-ASCII设备(标准输出):US-ASCIIstdout.encoding: US-ASCII设备(stderr):US-ASCIIstderr.encoding: US-ASCII设备(标准输入):US-ASCIIstdin.encoding: US-ASCII语言环境(假):US-ASCII语言环境(真):US-ASCII

python3 -S test-io-encoding.py:

Python 编码:无语言环境(假):US-ASCII设备(标准输出):US-ASCIIstdout.encoding: US-ASCII设备(stderr):US-ASCIIstderr.encoding: US-ASCII设备(标准输入):US-ASCIIstdin.encoding: US-ASCII语言环境(假):US-ASCII语言环境(真):US-ASCII

EDIT 尝试了@PauloBu 提供的hackerish"解决方案:

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

+-================================-+✂回溯(最近一次调用最后一次): 中的文件snippets-convert.py",第 357 行主要的()文件snippets-convert.py",第 44 行,在 main菜单()文件snippets-convert.py",第 52 行,在菜单中print("|	 "+sys.stdout.buffer.write(chr(9986).encode('UTF-8'))+" PySnipt'd "+ sys.stdout.buffer.write(chr(9986).encode('UTF-8'))+" 	|")类型错误:无法将int"对象隐式转换为 str

EDIT 添加了@PauloBu 修复的结果:

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

编辑:

以及他的修复:

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

解决方案

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

这意味着如果您的终端使用 ascii 作为编码,Python 会尝试将 scissor 字符编码为 ascii.当然,ascii 不支持它,所以你会得到 Unicode 解码错误.

这就是为什么您必须始终对输出进行显式编码.显式比隐式好 记得吗?要修复您的代码,您可以执行以下操作:

导入系统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(("|	 "+ chr(9986) +" PySnipt'd " + chr(9986)+" 	|").encode('utf8'))

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

希望这有帮助!

I'm working on a Python script that uses the scissor character (9986 - ✂) and I'm trying to port my code to Mac, but I'm running into this error.

The scissor character shows up fine when run from IDLE (Python 3.2.5 - OS X 10.4.11 iBook G4 PPC) and the code works entirely fine on Ubuntu 13.10, but when I attempt to run this in the terminal I get this error/traceback:

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 ("|	 ",snipper.decode(),"PySnipt'd",snipper.decode(),"	|")
UnicodeEncodeError: 'ascii' codec can't encode character 'u2702' in position 0: ordinal not in range(128)

and the code that is giving me the problem:

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

Doesn't this signal that the terminal doesn't have the capability to display that character? I know this is an old system, but it is currently the only system I have to use. Could the age of the OS is interfering with the program?

I've read over these questions:

What's causing this error? Is it the age of the system/OS, the version of Python, or some programming error?

EDIT: This error crops up later with this duplicate issue (just thought I'd add it as it is within the same program and is the same error):

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)

EDIT:

I went into the terminal character settings and it does in fact support that character (as you can see in this screenshot:

when I insert it into terminal it prints out this: 342234202 and when I press Enter I get this: -bash: ✂: command not found

EDIT Ran commands as @J.F. Sebastian asked:

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

EDIT Tried the "hackerish" solution provided by @PauloBu:

As you can see, this caused one (Yay!) scissor, but I am now getting a new error. Traceback/error:

+-=============================-+
✂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("|	 "+sys.stdout.buffer.write(chr(9986).encode('UTF-8'))+" PySnipt'd "+ sys.stdout.buffer.write(chr(9986).encode('UTF-8'))+" 	|")
TypeError: Can't convert 'int' object to str implicitly

EDIT Added results of @PauloBu's fix:

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

EDIT:

And his fix for his fix:

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

解决方案

When Python prints and output, it automatically encodes it to the target medium. If it is a file, UTF-8 will be used as default and everyone will be happy, but if it is a terminal, Python will figure out the encoding the terminal is using and will try to encode the output using that one.

This means that if your terminal is using ascii as encoding, Python is trying to encode scissor char to ascii. Of course, ascii doesn't support it so you get Unicode decode error.

This is why you always have to explicitly encode your output. Explicit is better than implicit remember? To fix your code you may do:

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

This seems a bit hackerish. You can also set PYTHONIOENCODING=utf-8 before executing the script. I'am uncomfortable with both solutions. Probably your console doesn't support utf-8 and you see gibberish. But your program will be behaving correctly.

What I strongly recommend if you definitely need to show correct output on your console is to set your console to use another encoding, one that support scissor character. (utf-8 perhaps). On Linux, that can be achieve by doing: export lang=UTF_8. On Windows you change the console's code page with chcp. Just figure out how to set utf8 in yours and IMHO that'll be the best solution.


You can't mix print and sys.stdout.write because they're basically the same. Regarding to your code, the hackerish way would be like this:

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

I suggest you to take a read at the docs to see what's going on under the hood with print function and with sys.stdout: http://docs.python.org/3/library/sys.html#sys.stdin

Hope this helps!

这篇关于UnicodeEncodeError: 'ascii' 编解码器无法对位置 0 中的字符进行编码:序号不在范围内 (128)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆