如何在python的finally块中捕获错误 [英] how to catch error in finally block in python

查看:95
本文介绍了如何在python的finally块中捕获错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以在try上看到几个主题-catch,但似乎并没有讨论来自finally本身的错误。我发现如果在finally块中,则不会处理该错误。最终进行管理的理想方式是什么?

I could see several topics on try - catch but doesnt seem to discuss errors if any from finally block itself. I found that the error is not handled if it is in finally block. What would be the ideal way to manage finally?

例如下面是一个邮件功能。如果try块中有任何错误,最后将执行 quit 方法,该方法本身不会启动,因此会发生未处理的错误。因此,最好确保在finally块中没有错误发生吗?

For eg. below is a mail function. if there is any error in try block, finally will execute the quit method which itself is not initiated so an unhandled error occurs. So is it better to ensure there is no errors occur in finally block?

def send_email(ldap, email_address, password, msg):
    try:
        message = MIMEMultipart('alternative')
        message['To'] = email.utils.formataddr(('Recipient', '%s@abc.com'%email_address))
        message['From'] = email.utils.formataddr(('Author', '%s@abc.com'%email_address))
        message['Subject'] = 'Sample subject'
        text = "%s"%msg
        html = MIMEText('<html><head></head><h2>data</h2><body><p>%s</p></body></html>'%msg,'html')

        message.attach(html)
        server = smtplib.SMTP(host="ip",port=0)
        server.set_debuglevel(True)

        # identify ourselves, prompting server for supported features
        server.ehlo()

        if server.has_extn('STARTTLS'):
            server.starttls()
            server.ehlo() 

        server.login(ldap, password)
        print "%s@abc.com, %s@abc.com, %s "%(email_address,email_address,message.as_string())
        server.sendmail('%s@abc.com'%email_address, "%s@abc.com"%email_address, message.as_string())
    finally:
        server.quit()


推荐答案

由于您的最终块仅用于确保服务器连接正确关闭,无论如何,显而易见的答案是仅将相关部分包装在 try 块中:

Since your finally block is only used to ensure the server connection is properly closed whatever, the obvious answer is to only wrap the relevant part in the try block:

def send_email(ldap, email_address, password, msg):
    message = MIMEMultipart('alternative')
    message['To'] = email.utils.formataddr(('Recipient', '%s@abc.com'%email_address))
    message['From'] = email.utils.formataddr(('Author', '%s@abc.com'%email_address))
    message['Subject'] = 'Sample subject'
    text = "%s"%msg
    html = MIMEText('<html><head></head><h2>data</h2><body><p>%s</p></body></html>'%msg,'html')

    message.attach(html)
    server = smtplib.SMTP(host="ip",port=0)

    # now you can start the try block:
    try:
        server.set_debuglevel(True)    
        # identify ourselves, prompting server for supported features
        server.ehlo()
        if server.has_extn('STARTTLS'):
            server.starttls()
            server.ehlo() 
        server.login(ldap, password)
        print "%s@abc.com, %s@abc.com, %s "%(email_address,email_address,message.as_string())
        server.sendmail('%s@abc.com'%email_address, "%s@abc.com"%email_address, message.as_string())
    finally:
        server.quit()

还有一个更好的解决方案是将此代码拆分为不同的功能,每个功能都具有明确定义的责任-准备消息,获得与服务器的连接等,即:

A still better solution would be to split this code in distinct functions each with a single well-defined responsability - preparing the message, getting a connection to the server etc, ie:

def prepare_message(sender, recipient, subject, msg):
    message = MIMEMultipart('alternative')
    message['To'] = email.utils.formataddr(('Recipient', recipient))
    message['From'] = email.utils.formataddr(('Author', sender))
    message['Subject'] = subject
    #text = "%s" % msg # this one is useless
    html = MIMEText("""
       <html>
         <head></head>
         <body>
           <h2>data</h2>
           <p>%s</p>
         </body>
        </html>""" % msg,
        'html'
        )
    message.attach(html)
    return message


def connect(ldap, password):
    server = smtplib.SMTP(host="ip",port=0)
    server.set_debuglevel(True)    
    # identify ourselves, prompting server for supported features
    server.ehlo()
    if server.has_extn('STARTTLS'):
        server.starttls()
        server.ehlo() 
    server.login(ldap, password)
    return server

def send_email(ldap, email_address, password, msg):
    sender = recipient = "%s@abc.com" % email_address
    message = prepare_message(sender, recipient, 'Sample subject', msg)
    server = connect(ldap, password)    
    try:
        server.sendmail(sender, recipient, message.as_string())
    finally:
        server.quit()

这篇关于如何在python的finally块中捕获错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆