gpt4 book ai didi

Python 不可重现的 UnicodeDecodeError

转载 作者:行者123 更新时间:2023-12-01 09:31:26 26 4
gpt4 key购买 nike

我正在尝试使用 Python 中的以下命令序列替换 Word 文件中的子字符串。代码本身工作得很好 - 即使使用完全相同的 Word 文件,但当将其嵌入到更大规模的项目结构中时,它会在确切的位置抛出错误。我不知道是什么原因导致它,因为它似乎与代码无关,并且对我来说似乎无法重现。

旁注:我知道导致错误的原因,它是 Word 文件中的德语“ü”,但它是必需的,如果代码独立工作,删除它似乎不是正确的解决方案。

#foo.py
from bar import make_wordm
def main(uuid):
with open('foo.docm', 'w+') as f:
f.write(make_wordm(uuid=uuid))

main('1cb02f34-b331-4616-8d20-aa1821ef0fbd')

foo.py 导入 bar.py 来完成繁重的工作。

#bar.py
import tempfile
import shutil
from cStringIO import StringIO
from zipfile import ZipFile, ZipInfo

WORDM_TEMPLATE='./res/template.docm'
MODE_DIRECTORY = 0x10

def zipinfo_contents_replace(zipfile=None, zipinfo=None,
search=None, replace=None):
dirname = tempfile.mkdtemp()
fname = zipfile.extract(zipinfo, dirname)
with open(fname, 'r') as fd:
contents = fd.read().replace(search, replace)
shutil.rmtree(dirname)
return contents

def make_wordm(uuid=None, template=WORDM_TEMPLATE):
with open(template, 'r') as f:
input_buf = StringIO(f.read())
output_buf = StringIO()
output_zip = ZipFile(output_buf, 'w')

with ZipFile(input_buf, 'r') as doc:
for entry in doc.filelist:
if entry.external_attr & MODE_DIRECTORY:
continue

contents = zipinfo_contents_replace(zipfile=doc, zipinfo=entry,
search="00000000-0000-0000-0000-000000000000"
, replace=uuid)
output_zip.writestr(entry, contents)
output_zip.close()
return output_buf.getvalue()

在更大规模的上下文中嵌入相同的代码时会引发以下错误:

ERROR:root:message
Traceback (most recent call last):
File "FooBar.py", line 402, in foo_bar
bar = bar_constructor(bar_theme,bar_user,uuid)
File "FooBar.py", line 187, in bar_constructor
if(main(uuid)):
File "FooBar.py", line 158, in main
f.write(make_wordm(uuid=uuid))
File "/home/foo/FooBarGen.py", line 57, in make_wordm
search="00000000-0000-0000-0000-000000000000", replace=uuid)
File "/home/foo/FooBarGen.py", line 24, in zipinfo_contents_replace
contents = fd.read().replace(search, replace)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2722: ordinal not in range(128)
INFO:FooBar:None

编辑:经过进一步检查和调试,似乎变量“uuid”导致了问题。当将参数作为全文字符串 ('1cb02f34-b331-4616-8d20-aa1821ef0fbd') 给出时,而不是使用从 JSON 解析的变量,它工作得非常好。

edit2:我必须添加 uuid = uuid.encode('utf-8', 'ignore') 现在它工作得很好。

最佳答案

问题在于混合 Unicode 和字节字符串。 Python 2“有效地”尝试从一种转换为另一种,但默认使用 ascii 编解码器。

这是一个例子:

>>> 'aeioü'.replace('a','b')  # all byte strings
'beio\xfc'
>>> 'aeioü'.replace(u'a','b') # one Unicode string and it converts...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 4: ordinal not in range(128)

您提到从 JSON 读取 UUID。 JSON 返回 Unicode 字符串。理想情况下,读取所有解码为 Unicode 的文本文件,以 Unicode 进行所有文本处理,并在写回存储时对文本文件进行编码。在你的“更大的框架”中,这可能是一项很大的移植工作,但本质上是使用 io.open 和编码来读取文件并解码为 Unicode:

with io.open(fname, 'r', encoding='utf8') as fd:
contents = fd.read().replace(search, replace)

请注意,编码应与您正在读取的文件的实际编码相匹配。这是你必须确定的事情。

正如您在编辑中发现的,快捷方式是将 UUID 从 JSON 编码回字节字符串,但目标应该是使用 Unicode 处理文本。

Python 3 通过默认将字符串设置为 Unicode 来清理此过程,并删除与字节/Unicode 字符串之间的隐式转换。

关于Python 不可重现的 UnicodeDecodeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49938517/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com