Python 中内部函数错误参数错误

问题描述 投票:0回答:2

我有一个使用 ReportLab 创建报告的 python 脚本,该脚本已经过测试并且按预期工作,但是有时我会收到以下错误消息

TraceBack info:

File "C:\tools\LegionellaTool.py", line 605, in <module>

createReport(selectedCoolingTowers, Report_outputs_folder, dbo_COLGIS, openPDF)

Error Info:

..\Objects\moduleobject.c:50: bad argument to internal function

605路是

createReport(selectedCoolingTowers, Report_outputs_folder, dbo_COLGIS, openPDF)

createReport 是...创建报告的函数。 我已经调试了代码,没有遇到任何错误,什么可能会导致错误出现,该错误仅偶尔发生,而在其他情况下,报告创建得很好。

编辑=====创建报告代码

def createReport(myReportTable, myReportFolder, M3Table, OpenPDF):
    global Author
    global TimeStamp

##    myReportTable = gp.GetParameterAsText(0)
##    myReportFolder = gp.GetParameterAsText(1)
##    M3Table = gp.GetParameterAsText(2)
##    OpenPDF = gp.GetParameterAsText(3)

    Author = getpass.getuser() #gets OS user name
    TimeStamp = str(datetime.datetime.now().hour) + ':' + str(datetime.datetime.now().minute) + ' on the ' + str(datetime.date.today().day) + '/' + str(datetime.date.today().month) + '/' + str(datetime.date.today().year) 

    #add time stamp to file name
    myFile = myReportFolder + os.sep + 'CoolingTowersForInspection_' + str(datetime.datetime.now().hour) + '_' + str(datetime.datetime.now().minute) + '_' + str(datetime.date.today().day) + '_' + str(datetime.date.today().month) + '_' + str(datetime.date.today().year) + '.pdf'
    c = reportlab.pdfgen.canvas.Canvas(myFile)

    #creates sectors array
    sectors = []
    sectors.append('NW')
    sectors.append('NE')
    sectors.append('SW')
    sectors.append('SE')

    for sector in sectors:
        #sector header
        #framePage(c, 'Cooling Towers for Inspection - ' + sector + ' sector')
        title = 'Cooling Towers for Inspection - ' + sector + ' sector'
        c.setFont('Helvetica',20) #title font
        c.drawString(reportlab.lib.units.inch, 10.5 * reportlab.lib.units.inch, title) #creates title

        c.setFont('Helvetica',10) #header and footer font

        #creates header
        c.drawCentredString(4.135 * reportlab.lib.units.inch, 0.75 * reportlab.lib.units.inch,
                                 'Report generated by ' + Author + ' at ' + TimeStamp + ' - Page %d' % c.getPageNumber())

        #creates footer
        c.drawCentredString(4.135 * reportlab.lib.units.inch, 11.00 * reportlab.lib.units.inch,
                                'Environmental Services')

        #draw a border
        c.setStrokeColorRGB(1,0,0)
        c.setLineWidth(5)
        c.line(0.8 * reportlab.lib.units.inch, reportlab.lib.units.inch, 0.8 * reportlab.lib.units.inch, 10.75 * reportlab.lib.units.inch)

        #reset carefully afterwards
        c.setLineWidth(1)
        c.setStrokeColorRGB(0,0,0)

        c.setFont('Helvetica', 10)

        #gets towers in that sector
        myTowers = arcpy.SearchCursor(myReportTable,"\"SECTOR\" = '" + sector + "'","","")
        selTower = myTowers.next()

        y = 730

        if selTower is not None:

            while selTower:
                #insert page break when close to the end of the page
                if y < 110:
                    c.showPage()
                    y = 730
                    framePage(c, 'Cooling Towers for Inspection - ' + sector + ' sector')

                if selTower.TOWER_NAME <> None:
                    c.drawString(100, y, string.strip(selTower.TOWER_NAME))
                else:
                    c.drawString(100, y, "na")
                y = y - 12

                if selTower.TOWER_ADDRESS <> None:
                    c.drawString(100, y, string.strip(selTower.TOWER_ADDRESS))
                else:
                    c.drawString(100, y, "na")
                y = y - 12

                c.drawString(100, y, "Number of towers: " + str(int(selTower.NUMBER_OF_TOWERS)) + " ;   M3 Code: " + selTower.UKEY + " ;   Distance band: " + str(int(selTower.distance)) + " meters")
                y = y - 12

                inspectString = ""
                if selTower.TOWER_RATING <> None:
                    inspectString = "Inspection rating: " + selTower.TOWER_RATING
                else:
                    inspectString = "Inspection rating: na;"

                if selTower.TOWER_LAST_INSPECTION <> None:
                    t = selTower.TOWER_LAST_INSPECTION
                    strLastInspection = t.strftime("%A, %d %b %Y")

                    inspectString = inspectString + "   Last inspection: " + strLastInspection
                    #inspectString = inspectString + "   Last inspection: " + selTower.TOWER_LAST_INSPECTION
                else:
                    inspectString = inspectString + "   Last inspection: na"

                c.drawString(100, y, inspectString)
                y = y - 12

                c.drawString(100, y, "Contacts:")
                y = y - 12

                myTowerUKEY = selTower.UKEY

                #gets contacts for that cooling tower            
                myTowerContacts = arcpy.SearchCursor(M3Table,"\"UKEY\" = '" + myTowerUKEY + "'","","")

                selContact = myTowerContacts.next()

                while selContact:
                    if y < 110:
                        c.showPage()
                        y = 730
                        framePage(c, 'Cooling Towers for Inspection - ' + sector + ' sector')

                    contact = ""
                    if selContact.TITLE <> None:
                        if string.strip(selContact.TITLE) <> "":
                            contact = string.strip(selContact.TITLE) + " "
                    if selContact.FIRSTNAME <> None:
                        contact = contact + selContact.FIRSTNAME + " "
                    if selContact.FAMILYNAME <> None:
                        contact = contact + selContact.FAMILYNAME + " "
                    if selContact.JOBTITLE <> None:
                        contact = contact + "(" + selContact.JOBTITLE + ") "
                    if selContact.TELW <> None:
                        contact = contact + selContact.TELW + "(work) "
                    if selContact.MOBILE <> None:
                        if string.strip(selContact.MOBILE) <> "":
                            contact = contact + string.strip(selContact.MOBILE) + "(mobile) "
                    if selContact.TELH <> None:
                        if string.strip(selContact.TELH) <> "":
                            contact = contact + string.strip(selContact.TELH) + "(home)"

                    contact = string.strip(contact)

                    c.drawString(100, y, contact)
                    y = y - 12
                    selContact = myTowerContacts.next()                

                y = y - 12
                del myTowerContacts
                selTower = myTowers.next()
        else:
            c.drawString(100, y, "no cooling towers for inspection in this sector")

        c.showPage() #insert page break after each sector

    del myTowers

    c.save()

    if OpenPDF == "true":
        os.startfile(myFile)

#function that creates each page
def framePage(canvas, title):
    canvas.setFont('Helvetica',20) #title font
    canvas.drawString(reportlab.lib.units.inch, 10.5 * reportlab.lib.units.inch, title) #creates title

    canvas.setFont('Helvetica',10) #header and footer font

    #creates header
    canvas.drawCentredString(4.135 * reportlab.lib.units.inch, 0.75 * reportlab.lib.units.inch,
                             'Report generated by ' + Author + ' at ' + TimeStamp + ' - Page %d' % canvas.getPageNumber())

    #creates footer
    canvas.drawCentredString(4.135 * reportlab.lib.units.inch, 11.00 * reportlab.lib.units.inch,
                            'Environmental Services')

    #draw a border
    canvas.setStrokeColorRGB(1,0,0)
    canvas.setLineWidth(5)
    canvas.line(0.8 * reportlab.lib.units.inch, reportlab.lib.units.inch, 0.8 * reportlab.lib.units.inch, 10.75 * reportlab.lib.units.inch)

    #reset carefully afterwards
    canvas.setLineWidth(1)
    canvas.setStrokeColorRGB(0,0,0)

编辑编号 2 *

完整的追溯在这里

Traceback (most recent call last):
  File "C:\tools\LegionellaTool.py", line 613, in <module>
    createReport(selectedCoolingTowers, Report_outputs_folder, dbo_COLGIS, openPDF)

  File "C:\tools\LegionellaTool.py", line 120, in createReport

    c.drawString(reportlab.lib.units.inch, 10.5 * reportlab.lib.units.inch, title) #creates title

  File "c:\python26\arcgis10.0\lib\site-packages\reportlab\pdfgen\canvas.py", line 1481, in drawString

    t.textLine(text)

  File "c:\python26\arcgis10.0\lib\site-packages\reportlab\pdfgen\textobject.py", line 426, in textLine

    self._code.append('%s T*' % self._formatText(text))
  File "c:\python26\arcgis10.0\lib\site-packages\reportlab\pdfgen\textobject.py", line 393, in _formatText

    for f, t in pdfmetrics.unicode2T1(text,[font]+font.substitutionFonts):
SystemError: ..\Objects\moduleobject.c:50: bad argument to internal function

<type 'exceptions.SystemExit'>: 1

谢谢

python reportlab
2个回答
0
投票

根据我的经验,ReportLab 的间歇性错误通常是由尝试渲染可能包含“奇怪”内容的文本时出现的问题引起的,例如字符集的意外字符或空值。查看您的代码,我没有注意到任何明显会导致问题的内容,但您可能想研究某些内容包含意外值的可能性。

特别是,我会查看处理

selContact
的代码,看看它的任何属性是否意外为空或只是不是可能导致错误的字符串。

没有完整的堆栈跟踪,很难说出更具体的内容。

预计到达时间

根据现在提供的堆栈跟踪,看起来问题要么出在您尝试绘制的

title
变量中,要么出在用于绘制字符串的字体上。不过,查看您的代码,我没有注意到任何问题,也没有任何迹象表明引发错误的代码部分存在间歇性问题。


0
投票

在过去的几周里,这条消息让我发疯,我终于弄清楚了导致此错误的两件事以及如何修复它们:

  • 正如 G Gordon Worley III 建议的那样,如果您尝试使用不正确的元素构建报告,它可能会出现。

    修复:查找哪个元素已损坏或在 ArcGIS 之外调试您的程序,您将获得更明确的错误消息。

  • 如果你的Python安装有点混乱,它可能会出现。对我来说,我将 ReportLab 文件包含在与脚本相同的文件夹中,以使其更易于分发。但我之前也在我的 Python 安装文件夹中安装了 ReportLab。不知何故,这让 ArcGIS 感到困惑。

    修复:删除Python??/(ArcGIS??.?/)Lib/site-packages/reportlab文件夹,以便您的脚本只有一个库选项。

我希望这会对某人有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.