【发布时间】:2018-04-20 09:33:05
【问题描述】:
我正在尝试使用 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'),现在它工作得很好。
【问题讨论】:
-
在您的
open上,您没有指定编码。如果它在某个时候起作用,并不意味着它是正确的。 Python 口头禅:“显式优于隐式”。注意:大型框架可以激活“语言环境”,因此它可以改变本地部分的行为(以及 ev. translate 也可以)
标签: python unicode ascii decode