Python UnicodeEncodeError: 'ascii' 编解码器无法对位置 0 中的字符进行编码:序号不在范围内 (128)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20923663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 21:33:32  来源:igfitidea点击:

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

pythonencodingpython-3.2

提问by RPiAwesomeness

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.

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

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:

从 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)

and the code that is giving me the problem:

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

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

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:

我已经阅读了这些问题:

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

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

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:

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

enter image description here

在此处输入图片说明

when I insert it into terminal it prints out this: \342\234\202and when I press EnterI get this: -bash: ?: command not found

当我将它插入终端时,它会打印出这个:\342\234\202当我按下时,Enter我得到了这个:-bash: ?: command not found

EDITRan commands as @J.F. Sebastian asked:

编辑Ran 命令,@JF Sebastian 问:

python3 test-io-encoding.py:

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:

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

EDITTried the "hackerish" solution provided by @PauloBu:

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

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

EDITAdded results of @PauloBu's fix:

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

+-=============================-+
|
? PySnipt'd 
?       |
+-=============================-+

EDIT:

编辑

And his fix for his fix:

以及他对他的修复的修复:

+-=============================-+
??|       PySnipt'd     |
+-=============================-+

采纳答案by Paulo Bu

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.

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

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

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

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.

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

What I strongly recommend if you definitelyneed to show correct output on your console is to set your console to use another encoding, one that support scissorcharacter. (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.

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



你不能混合printprintsys.stdout.writesys.stdout.write因为它们基本上是一样的。关于你的代码,黑客的方式是这样的:

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 printfunction and with sys.stdout: http://docs.python.org/3/library/sys.html#sys.stdin

我建议您阅读文档以了解print功能和功能背后发生了什么sys.stdouthttp: //docs.python.org/3/library/sys.html#sys.stdin

Hope this helps!

希望这可以帮助!

回答by archetipo

in the first line of your file .py you need to add this string, :

在文件 .py 的第一行中,您需要添加以下字符串:

# -- coding: utf-8 --

# - - 编码:utf-8 --

and you can also try this:

你也可以试试这个:

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

打印 ("|\t ",unichr(9986),"PySnipt'd",unichr(9986),"\t|")

回答by jfs

test_io_encoding.pyoutput suggests that you should change your localesettings e.g., set LANG=en_US.UTF-8.

test_io_encoding.py输出建议您应该更改locale设置,例如 set LANG=en_US.UTF-8



The first error might be due to you are trying to decode a string that is already Unicode. Python 2 tries to encode it using a default character encoding ('ascii') beforedecoding it using (possibly) different character encoding. The error happens on the encodestep:

第一个错误可能是由于您试图解码一个已经是 Unicode 的字符串。Python 2 尝试使用默认字符编码 ( 'ascii')对其进行编码,然后再使用(可能)不同的字符编码对其进行解码。错误发生在encode步骤上:

>>> u"\u2702".decode() # Python 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2702' in position 0: ordinal not in range(128)

It looks like you are running your script using Python 2 instead of Python 3. You would get:

看起来您正在使用 Python 2 而不是 Python 3 运行您的脚本。您会得到:

>>> "\u2702".decode() # Python 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'decode'

different error otherwise.

否则不同的错误。

Just drop the .decode()call:

只需挂断.decode()电话:

print("|\t {0} PySnipt'd {0} \t|".format(snipper))

The second issue is due to printing a Unicode string into a pipe:

第二个问题是由于将 Unicode 字符串打印到管道中:

$ python3 -c'print("\u2702")'
?
$ python3 -c'print("\u2702")' | cat
Traceback (most recent call last):
  File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u2702' in position 0: ordinal not in range(128)

Set appropriate for your purpose PYTHONIOENCODINGenvironment variable:

设置适合您目的的PYTHONIOENCODING环境变量:

$ PYTHONIOENCODING=utf-8 python3 -c'print("\u2702")' | cat
?


the terminal is just displaying this: | b'\xe2\x9c\x82' PySnipt'd b'\xe2\x9c\x82' |

终端只是显示这个: | b'\xe2\x9c\x82' PySnipt'd b'\xe2\x9c\x82' |

If snipperis a bytesobject then leave the snipper.decode()calls.

如果snipper是一个bytes对象,则离开snipper.decode()调用。

$ python3 -c"print(b'\xe2\x9c\x82'.decode())"
?
$ python3 -c"print(b'\xe2\x9c\x82'.decode())" | cat
Traceback (most recent call last):
  File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u2702' in position 0: ordinal not in range(128)

The fix is the same:

修复方法是一样的:

$ PYTHONIOENCODING=utf-8 python3 -c"print(b'\xe2\x9c\x82'.decode())" | cat
?

回答by Mike Mitterer

My locale is set to de_AT.UTF-8 but these lines in /etc/profilewere missing:

我的语言环境设置为 de_AT.UTF-8 但/etc/profile缺少这些行:

export LANG=de_AT.UTF-8
export LANGUAGE=de_AT.UTF-8
export LC_ALL=de_AT.UTF-8

logout / login and your problem should be solved

注销/登录,您的问题应该得到解决

To verify if all locales are set correctly type localein your terminal

要验证是否所有语言环境都设置正确locale,请在您的终端中输入

The output should be similar to this:

输出应该类似于:

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