首页 > 解决方案 > 错误 Unicode 对象必须在散列之前进行编码

问题描述

我想创建一个带有指向另一个脚本的超链接的 ToC,并想了解它是如何工作的,但我无法让它与我找到的这个示例一起工作。你可以帮帮我吗?我刚刚收到错误消息:

Unicode 对象必须在散列之前进行编码

这是整个示例: https ://www.reportlab.com/snippets/13/

#this function makes our headings
def doHeading(text,sty):
    from hashlib import sha1
    #create bookmarkname
    bn=sha1(text+sty.name).hexdigest()
    #modify paragraph text to include an anchor point with name bn
    h=Paragraph(text+'<a name="%s"/>' % bn,sty)
    #store the bookmark name on the flowable so afterFlowable can see this
    h._bookmarkName=bn
    story.append(h)

story.append(Paragraph('<b>Table of contents</b>', centered))
story.append(PageBreak())
doHeading('First heading', h1)
story.append(Paragraph('Text in first heading', PS('body')))
doHeading('First sub heading', h2)
story.append(Paragraph('Text in first sub heading', PS('body')))
story.append(PageBreak())
doHeading('Second sub heading', h2)
story.append(Paragraph('Text in second sub heading', PS('body')))
story.append(PageBreak())
doHeading('Last heading', h1)
story.append(Paragraph('Text in last heading', PS('body')))
doc = MyDocTemplate('mintoc.pdf')
doc.multiBuild(story)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-16-138d578aa6aa> in <module>
     83 story.append(Paragraph('<b>Table of contents</b>', centered))
     84 story.append(PageBreak())
---> 85 doHeading('First heading', h1)
     86 story.append(Paragraph('Text in first heading', PS('body')))
     87 doHeading('First sub heading', h2)

<ipython-input-16-138d578aa6aa> in doHeading(text, sty)
     74     from hashlib import sha1
     75     #create bookmarkname
---> 76     bn=sha1(text+sty.name).hexdigest()
     77     #modify paragraph text to include an anchor point with name bn
     78     h=Paragraph(text+'<a name="%s"/>' % bn,sty)

TypeError: Unicode-objects must be encoded before hashing

标签: pythonunicodereportlabtableofcontents

解决方案


示例代码适用于 Python 2。我可以使用 Python 3 重现此错误。作为参考,完整的回溯是:

Traceback (most recent call last):
  File "example.py", line 85, in <module>
    doHeading('First heading', h1)
  File "example.py", line 76, in doHeading
    bn=sha1(text+sty.name).hexdigest()
TypeError: Unicode-objects must be encoded before hashing

原因是该方法sha1()需要字节,而不是字符串。Python 2 对字符串处理不那么严格,这就是它不给出异常的原因。

所以你有两个选择:要么使用 Python 2(不推荐用于新代码),要么你可以更新代码以使用 Python 3。我可以通过两个小的修改来获得这个特定的示例:

在第 76 行,替换

bn=sha1(text+sty.name).hexdigest()

经过

bn=sha1((text+sty.name).encode('ascii')).hexdigest()

在第 11 行,apply()正在使用,自 Python 2.3 起已弃用。要更新,更换

apply(BaseDocTemplate.__init__, (self, filename), kw)

经过

BaseDocTemplate.__init__(*(self, filename), **kw)

请注意,具有这些修改的示例在 Python 2 和 3(使用 2.7 和 3.6 测试)中运行良好。


推荐阅读