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

 明天流浪远方 发布于 2023-02-06 15:57

我正在使用一个使用剪刀字符(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 
    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|")

这是否表示终端无法显示该字符?我知道这是一个旧系统,但它是我目前唯一使用的系统.操作系统的时代是否会干扰该计划?

我读过这些问题:

UnicodeEncodeError:'ascii'编解码器无法对位置0中的字符u'\ xef'进行编码:序数不在范围内(128) - 不同的字符

"UnicodeEncodeError:'ascii'编解码器不能编码字符" - 使用2.6,所以不知道它是否适用

UnicodeEncodeError:'ascii'编解码器无法编码字符?- 似乎是我的问题的合理解决方案.encode('UTF-8'),我没有得到错误.但是,它显示的是字符代码,而不是我想要的字符,.decode()只是给了我同样的错误.不确定我是否正确行事.

UnicodeEncodeError:'ascii'编解码器无法编码位置0-6中的字符:序数不在范围内(128) - 不确定是否适用,他使用GUI,获取输入,全部使用希腊语.

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

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

Traceback (most recent call last):
  File "snippets-convert.py", line 353, in 
    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)

编辑:

我进入了终端字符设置,它实际上支持该字符(正如您在此屏幕截图中看到的那样:

在此输入图像描述

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

编辑 Ran命令为@JF Sebastian问:

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提供的"黑客"解决方案:

正如你所看到的,这导致了一个(Yay!)剪刀,但我现在遇到了一个新的错误.回溯/错误:

+-=============================-+
?Traceback (most recent call last):
  File "snippets-convert.py", line 357, in 
    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     |
+-=============================-+

Paulo Bu.. 21

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

这意味着如果您的终端使用ascii编码,Python正在尝试将scissorchar 编码为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.只是弄清楚如何在你的设置和恕我直言,这将是最好的解决方案.


你不能混合print,sys.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

希望这可以帮助!

2 个回答
  • test_io_encoding.py输出表明您应该更改您的locale设置,例如,设置LANG=en_US.UTF-8.


    第一个错误可能是由于您尝试解码已经是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)
    

    看起来您正在使用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'
    

    否则会出现其他错

    只需放下.decode()电话:

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

    第二个问题是由于将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)
    

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

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

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

    如果snipperbytes对象,则保留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)
    

    修复是一样的:

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

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

    这意味着如果您的终端使用ascii编码,Python正在尝试将scissorchar 编码为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.只是弄清楚如何在你的设置和恕我直言,这将是最好的解决方案.


    你不能混合print,sys.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

    希望这可以帮助!

    2023-02-06 15:59 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有