UnicodeEncodeError:'ascii'编解码器不能在0位编码字符:ordinal不在范围(128) [英] UnicodeEncodeError: 'ascii' codec can't encode character in position 0: ordinal not in range(128)
问题描述
我正在使用一个使用剪刀字符(9986 - ✂)的Python脚本,我正在尝试将我的代码移植到Mac,但是我遇到了这个错误。
从IDLE(Python 3.2.5 - OS X 10.4.11 iBook G4 PPC)运行时,剪刀字符显示良好,代码在Ubuntu 13.10上运行正常,但是当我尝试运行终端我得到这个错误/追溯:
追溯(最近的最后一次呼叫):
文件片段转换.py,第352行,< module>
main()
文件snippets-convert.py,第41行,主
菜单()
文件snippets-convert.py,第47行,菜单
print(| \t,snipper.decode(),PySnipt'd,snipper.decode(),\t |)
UnicodeEncodeError:'ascii'在第0位编码字符\\\✂:序号不在范围内(128)
给我这个问题的代码:
print(| \t,chr(9986),PySnipt'd,chr (9986),\t |)
这不表示终端没有能力显示字符?我知道这是一个旧系统,但它是目前唯一需要使用的系统。操作系统的时代可能会干扰程序吗?
我已经阅读了以下问题:
-
希望这有帮助!
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 ("|\t ",snipper.decode(),"PySnipt'd",snipper.decode(),"\t|") 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 ("|\t ",chr(9986),"PySnipt'd",chr(9986),"\t|")
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:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xef' in position 0: ordinal not in range(128) - Different character
"UnicodeEncodeError: 'ascii' codec can't encode character" - Using 2.6, so don't know if it applies
UnicodeEncodeError: 'ascii' codec can't encode character? - Seems to be a plausible solution to my problem,
.encode('UTF-8')
, I don't get the error. However, it displays a character code, not the character I want, and.decode()
just gives me the same error. Not sure if I'm doing this right.UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-6: ordinal not in range(128) - Not sure if this applies, he's using a GUI, getting input, and all in Greek.
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:
\342\234\202
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("|\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
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 encodescissor
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 withchcp
. Just figure out how to set utf8 in yours and IMHO that'll be the best solution.
You can't mixprint
andsys.stdout.write
because they're basically the same. Regarding to your code, the hackerish way would be like this:sys.stdout.buffer.write(("|\t "+ chr(9986) +" PySnipt'd " + chr(9986)+" \t|").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 withsys.stdout
: http://docs.python.org/3/library/sys.html#sys.stdinHope this helps!
这篇关于UnicodeEncodeError:'ascii'编解码器不能在0位编码字符:ordinal不在范围(128)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!