【问题标题】:how to properly use try/except/with inside functions and main如何正确使用 try/except/with 内部函数和 main
【发布时间】:2014-11-15 17:57:09
【问题描述】:

我是一个相对的 python 新手,我对如何正确处理异常感到困惑。为愚蠢的问题道歉。

在我的 main() 中,我遍历日期列表,并为每个日期调用一个函数,该函数从公共 Web 服务器下载 csv 文件。出于明显的原因,我想正确捕获异常,但尤其是因为我不知道感兴趣的文件何时可以下载。我的程序将作为 cron 作业的一部分执行,并会尝试每 3 小时下载一次这些文件(如果可用)。

我想要的是下载日期列表中的第一个文件,如果这导致 404,那么程序不应继续执行下一个文件,因为假设如果列表中最旧的日期不可用,那么之后的其他任何一个都将不可用。

我有以下 python 伪代码。我在尝试下载文件的函数内部有 try/except 块,但是如果函数内部发生异常,我如何在 main() 中正确处理它,以便我可以决定是否继续到下一个日期。我创建一个函数来执行下载的原因是因为我想稍后在同一个 main() 块中为其他文件类型重用该代码。

def main():
...
...
# datelist is a list of date objects
    for date in datelist:
        download_file(date)

def download_file(date):
    date_string = str(date.year) + str(date.strftime('%m')) + str(date.strftime('%d'))
    request = HTTP_WEB_PREFIX+ date_string + FILE_SUFFIX
    try: 
        response = urllib2.urlopen(request)
    except urllib2.HTTPError, e:
        print "HTTPError = " + str(e)
    except urllib2.URLError, e:
        print "URLError = " + str(e)
    except httplib.HTTPException, e:
        print "HTTPException = " + str(e)  
    except IOError:
        print "IOError = " + str(e)
    except Exception:
        import traceback
        print "Generic exception: " + traceback.format_exc()
    else: 
        print "No problem downloading %s - continue..." % (response)
        try: 
            with open(TMP_DOWNLOAD_DIRECTORY + response, 'wb') as f:
        except IOError:
            print "IOError = " + str(e)
        else:
            f.write(response.read())
        f.close()

【问题讨论】:

    标签: python with-statement try-except


    【解决方案1】:

    这里的关键概念是,如果你能解决问题,你应该捕获异常;如果不能,那就是调用者的问题要处理。在这种情况下,如果文件不存在,下载器将无法修复问题,因此它应该将其异常冒泡给调用者;如果出现异常,调用者应该知道停止循环。

    因此,让我们将所有异常处理从函数中移到循环中,并修复它,以便在下载文件失败时退出,按照规范的要求:

    for date in datelist:
            date_string = str(date.year) + 
                          str(date.strftime('%m')) + 
                          str(date.strftime('%d'))
        try:
            download_file(date_string)
        except:
            e = sys.exc_info()[0]
            print ( "Error downloading for date %s: %s" % (date_string, e) )
            break
    

    download_file 现在应该,除非您想进行重试或类似的操作,否则根本不捕获异常。由于您已经在调用者中随意解码了日期,因此该代码也可以来自download_file,从而更简单

    def download_file(date_string):
        request = HTTP_WEB_PREFIX + date_string + FILE_SUFFIX
        response = urllib2.urlopen(request) 
        print "No problem downloading %s - continue..." % (response)
        with open(TMP_DOWNLOAD_DIRECTORY + response, 'wb') as f:
            f.write(response.read())
            f.close()
    

    我建议print 语句是多余的,但如果你真的想要它,使用logger 是一种更灵活的前进方式,因为这将允许你稍后根据需要打开或关闭它更改配置文件而不是代码。

    【讨论】:

    • 非常周到的解释。它帮助我更好地理解所涉及的概念。我很感激。非常感谢。
    【解决方案2】:

    根据我对您的问题的理解...您应该只将代码插入到遇到特定异常时要执行的异常块中。您不必打印遇到的错误,您可以在出现错误时执行您认为有必要的任何操作...提供一个带有信息/选项的弹出框,或者以其他方式将您的程序引导到下一步。您的 else 部分应该隔离该部分,因此只有在没有引发任何异常时才会执行。

    【讨论】:

      猜你喜欢
      • 2011-05-08
      • 1970-01-01
      • 2012-11-06
      • 2013-04-12
      • 1970-01-01
      • 2018-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多