我是一个相对的 python 新手,我对如何正确处理异常感到困惑。为愚蠢的问题道歉。
在我的 main() 中,我遍历日期列表,并为每个日期调用一个函数,该函数从公共(public) Web 服务器下载一个 csv 文件。出于显而易见的原因,我想正确捕获异常,但尤其是因为我不知道何时可以下载感兴趣的文件。我的程序将作为 cron 作业的一部分执行,并将尝试每 3 小时下载一次这些文件(如果可用)。
我想要的是下载日期列表中的第一个文件,如果结果为 404,则程序不应继续处理下一个文件,因为假设列表中最早的日期不可用之后的其他人也将不可用。
我有以下 python 伪代码。我在尝试下载文件的函数内部有 try/except block ,但如果函数内部发生异常,我该如何在 main() 中正确处理它,以便我可以决定是否继续到下一个日期。我创建一个函数来执行下载的原因是因为我想稍后在同一 main() block 中为其他文件类型重新使用该代码。
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()
最佳答案
这里的关键概念是,如果你能解决问题,你应该捕获异常;如果不能,那就是调用者的问题了。在这种情况下,如果文件不存在,下载器将无法解决问题,因此它应该将异常冒泡给调用者;如果出现异常,调用者应该知道停止循环。
所以让我们将所有异常处理从函数中移到循环中,并修复它,以便在下载文件失败时它会崩溃,正如规范所要求的那样:
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
是一种更灵活的前进方式,因为这将允许你稍后通过更改配置文件而不是代码来根据需要打开或关闭它。
关于python - 如何正确使用 try/except/with 内部函数和 main,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25962710/