python - Python 中打印函数的奇怪行为:OSError [WinError 87]
问题描述
背景
当试图打印某个字符串时,python 解释器完全崩溃了。没有后续的 print 或 repr 操作工作,显示被窃听等。
此错误仅在 Windows 10、Python 3.7.4 中重现。在线口译员处理得很好。
最小可重现代码:
a = b'@badge-info=;badges=;color=#1E90FF;display-name=HuwoBot;emotes=;flags=;id=ace1f2cc-54ac-4889-8d25-fc64cacc3f8c;mod=0;room-id=22484632;subscriber=0;tmi-sent-ts=1587751046231;turbo=0;user-id=64313471;user-type= :huwobot!huwobot@huwobot.tmi.twitch.tv PRIVMSG #forsen :57 users failed to beat the raid level [1505] - No experience rewarded!\xf0\x9f\x92\x80 \xf3\xa0\x80\x80\r'
print(a.decode('utf-8'))
注意:我将字符串编码为 UTF-8 以将其发布到此处。据我所知,UTF-8 编码与错误无关。
注意2:没有打印,即不会发生此错误a.decode('utf-8')
。
注意3:这个字符串的奇怪之处在于,通过删除除最后一个字符之外的任何字符都不会产生错误。
出错后
出错后我做的事情:
- 打印了一个字符串,这导致了同样的错误。
- Typed
'abc'
,这导致了同样的错误。 - 退出控制台,这再次引发了错误并打印了两个未打印的字符串。
我的问题是
- 究竟是什么导致了这个错误?
- 为什么这个错误会完全破坏 shell?
解决方案
根据https://en.wikipedia.org/wiki/Tags_(Unicode_block),您尝试打印的字符(\U000e0000
特别是)被标记为未分配。
大多数网站(例如https://fileformat.info)将这些字符标记为无效。例如,\U000e0000被标记为“无效的 Unicode 字符”,而\U000e0001被标记为“有效的 Unicode 字符”。
当 python/windows 尝试解释这些字符时,最有可能出现问题 - 也许它们发出执行某些操作的信号?为了解决这个问题,您可以将这些字符替换为其他字符。默认情况下,Unicode 通常使用“替换字符” \uFFFD来替换值未知或在 Unicode 中无法表示的字符。否则,您可以简单地删除这些字符。
import re
invalid_unicode_re = re.compile(u'[\U000e0000\U000e0002-\U000e001f]', re.UNICODE)
def replace_invalid_unicode(text, replacement_char=u'\uFFFD'):
return invalid_unicode_re.sub(replacement_char, text)
# Example use-case:
text = b'@badge-info=;badges=;color=#1E90FF;display-name=HuwoBot;emotes=;flags=;id=ace1f2cc-54ac-4889-8d25-fc64cacc3f8c;mod=0;room-id=22484632;subscriber=0;tmi-sent-ts=1587751046231;turbo=0;user-id=64313471;user-type= :huwobot!huwobot@huwobot.tmi.twitch.tv PRIVMSG #forsen :57 users failed to beat the raid level [1505] - No experience rewarded!\xf0\x9f\x92\x80 \xf3\xa0\x80\x80\r'
safe_to_print = replace_invalid_unicode(text.decode('utf-8')) # use replacement character
print(safe_to_print)
safe_to_print = replace_invalid_unicode(text.decode('utf-8'), '') # remove character
print(safe_to_print)
推荐阅读
- ios - 左或右对齐自定义 UITableView 单元格的 shouldShowMenuForRowAt 菜单
- apache-spark - 使用 Spark 结构化流将数据写入 JSON 数组
- daemon - 如何停止 janus-gateway 后台模式?
- javascript - Django 使用 Json 创建雷达图
- java - 尝试使用 Java JGit 从 Github 中提取日志
- flutter - 状态栏的高度
- amazon-web-services - 在 Terraform 中,如何从对象数组中输出列表?
- node.js - 导入 fs 模块时出现“ReferenceError:未定义要求”
- reactjs - 执行 create-react-app 以创建新的反应应用程序时出错
- sql - PostgreSQL 将表列结果保存到变量中