在使用 Python 编程时,遇到了一个错误 RuntimeError: maximum recursion depth exceeded。该错误发生的原因是代码中存在递归调用,导致调用堆栈深度过大,超过了 Python 解释器的最大递归深度限制。
在本文中,我将介绍如何解决此错误,并提供一个代码示例来说明解决方案。
2、解决方案
为了解决此错误,我们需要找到代码中存在递归调用的位置,并将其改为迭代实现。
在本文的代码示例中,错误发生在 updateShelfWithTabBody 函数中,该函数负责更新一个存储了歌曲详细信息的 shelf 文件。
def updateShelfWithTabBody(shelfFileName, newShelfFileName):
"""this function updates songDetails with
html body i.e. just the part that contains lyrics and
chords in the tab """
# read all songDetails
shelf = shelve.open(shelfFileName)
listOfKeys = shelf.keys()
# create new songDetails object
temporaryShelfObject = SongDetails.SongDetails()
# iterate over list of keys
for key in listOfKeys:
# print "name:"+shelf[key].name
# fill details from temporaryShelfObject
temporaryShelfObject.name = shelf[key].name
temporaryShelfObject.tabHtmlPageContent = shelf[key].tabHtmlPageContent
# add new detail information
htmlPageContent = shelf[key].tabHtmlPageContent
temporaryShelfObject.htmlBodyContent = extractDataFromDocument.fetchTabBody(htmlPageContent)
# write SongDetails back to shelf
writeSongDetails.writeSongDetails(temporaryShelfObject, newShelfFileName)
在该函数中,extractDataFromDocument.fetchTabBody 函数被调用来提取歌曲的正文内容。
def fetchTabBody(page_contents):
soup = BeautifulSoup(page_contents)
HtmlBody = ""
try:
#The lyrics and chords of song are contained in div with id = "cont"
#Note: This assumtption is specific to ultimate-guitar.com
HtmlBody = soup.html.body.find("div",{"id":"cont"})
except:
print "Error: ",sys.exc_info()[0]
return HtmlBody
该函数内部使用了递归调用,导致调用堆栈深度过大,超过了 Python 解释器的最大递归深度限制。
为了解决这个问题,我们可以将该函数改为迭代实现。
def fetchTabBody(page_contents):
soup = BeautifulSoup(page_contents)
HtmlBody = ""
for child in soup.html.body.find("div",{"id":"cont"}).descendants:
if child.name in ["p","br"]:
HtmlBody += str(child)
return HtmlBody
通过将 extractDataFromDocument.fetchTabBody 函数改为迭代实现,我们可以避免递归调用,从而解决 RuntimeError: maximum recursion depth exceeded 错误。
代码示例
以下是一个完整的代码示例,演示了如何解决 RuntimeError: maximum recursion depth exceeded 错误。
import shelve
import BeautifulSoup
import sys
class SongDetails:
name = ""
tabHtmlPageContent = ""
genre = ""
year = ""
artist = ""
chordsAndLyrics = ""
htmlBodyContent = ""
scale = ""
chordsUsed = []
def updateShelfWithTabBody(shelfFileName, newShelfFileName):
"""this function updates songDetails with
html body i.e. just the part that contains lyrics and
chords in the tab """
# read all songDetails
shelf = shelve.open(shelfFileName)
listOfKeys = shelf.keys()
# create new songDetails object
temporaryShelfObject = SongDetails.SongDetails()
# iterate over list of keys
for key in listOfKeys:
# print "name:"+shelf[key].name
# fill details from temporaryShelfObject
temporaryShelfObject.name = shelf[key].name
temporaryShelfObject.tabHtmlPageContent = shelf[key].tabHtmlPageContent
# add new detail information
htmlPageContent = shelf[key].tabHtmlPageContent
temporaryShelfObject.htmlBodyContent = fetchTabBody(htmlPageContent)
# write SongDetails back to shelf
writeSongDetails.writeSongDetails(temporaryShelfObject, newShelfFileName)
def fetchTabBody(page_contents):
soup = BeautifulSoup(page_contents)
HtmlBody = ""
for child in soup.html.body.find("div",{"id":"cont"}).descendants:
if child.name in ["p","br"]:
HtmlBody += str(child)
return HtmlBody
def writeSongDetails(songDetails, shelfFileName):
shelf = shelve.open(shelfFileName)
songDetails.name = str(songDetails.name).strip(' ')
shelf[songDetails.name] = songDetails
shelf.close()
if __name__ == "__main__":
shelfFileName = "songDetails.shelf"
newShelfFileName = "newSongDetails.shelf"
updateShelfWithTabBody(shelfFileName, newShelfFileName)
在该代码示例中,我们将 extractDataFromDocument.fetchTabBody 函数改为迭代实现,避免了递归调用,从而解决了 RuntimeError: maximum recursion depth exceeded 错误。