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

时间:2019-04-18 13:31:44

标签: python unicode reportlab tableofcontents

我想创建一个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

1 个答案:

答案 0 :(得分:1)

示例代码适用于Python2。我可以使用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测试)中运行良好。