gpt4 book ai didi

python - 在 Python 中处理异常的正确方法?

转载 作者:IT老高 更新时间:2023-10-28 22:15:06 24 4
gpt4 key购买 nike

我已经搜索了其他帖子,因为我觉得这是一个相当普遍的问题,但是我发现的所有其他 Python 异常问题都没有反射(reflect)我的问题。

我会在这里尽可能具体,所以我会举一个直接的例子。并且请不要针对此特定问题发布任何解决方法。我对如何使用 xyz 更好地发送电子邮件并不特别感兴趣。我想知道您通常如何处理相关的、容易出错的语句。

我的问题是,如何很好地处理相互依赖的异常,意思是:仅当第一步成功时,再尝试下一步,依此类推。另一个标准是:必须捕获所有异常,此代码必须是健壮的。

举个例子:

try:
server = smtplib.SMTP(host) #can throw an exception
except smtplib.socket.gaierror:
#actually it can throw a lot more, this is just an example
pass
else: #only if no exception was thrown we may continue
try:
server.login(username, password)
except SMTPAuthenticationError:
pass # do some stuff here
finally:
#we can only run this when the first try...except was successful
#else this throws an exception itself!
server.quit()
else:
try:
# this is already the 3rd nested try...except
# for such a simple procedure! horrible
server.sendmail(addr, [to], msg.as_string())
return True
except Exception:
return False
finally:
server.quit()

return False

这对我来说看起来非常不合 Python,错误处理代码是真实业务代码的三倍,但另一方面,我如何处理多个相互依赖的语句,这意味着语句 1 是语句 2 的先决条件,依此类推?

我也对适当的资源清理很感兴趣,即使是 Python 也可以自行管理。

谢谢,汤姆

最佳答案

您可以在出错时简单地返回,而不是使用 try/except 的 else block :

def send_message(addr, to, msg):
## Connect to host
try:
server = smtplib.SMTP(host) #can throw an exception
except smtplib.socket.gaierror:
return False

## Login
try:
server.login(username, password)
except SMTPAuthenticationError:
server.quit()
return False

## Send message
try:
server.sendmail(addr, [to], msg.as_string())
return True
except Exception: # try to avoid catching Exception unless you have too
return False
finally:
server.quit()

这是完全可读和 Pythonic..

另一种方法是,不必担心具体的实现,而是决定您希望代码的外观,例如..

sender = MyMailer("username", "password") # the except SocketError/AuthError could go here
try:
sender.message("addr..", ["to.."], "message...")
except SocketError:
print "Couldn't connect to server"
except AuthError:
print "Invalid username and/or password!"
else:
print "Message sent!"

然后为 message() 方法编写代码,捕捉您期望的任何错误,并提出您自己的自定义错误,并在相关的地方处理它。你的类(class)可能看起来像..

class ConnectionError(Exception): pass
class AuthError(Exception): pass
class SendError(Exception): pass

class MyMailer:
def __init__(self, host, username, password):
self.host = host
self.username = username
self.password = password

def connect(self):
try:
self.server = smtp.SMTP(self.host)
except smtplib.socket.gaierror:
raise ConnectionError("Error connecting to %s" % (self.host))

def auth(self):
try:
self.server.login(self.username, self.password)
except SMTPAuthenticationError:
raise AuthError("Invalid username (%s) and/or password" % (self.username))

def message(self, addr, to, msg):
try:
server.sendmail(addr, [to], msg.as_string())
except smtplib.something.senderror, errormsg:
raise SendError("Couldn't send message: %s" % (errormsg))
except smtp.socket.timeout:
raise ConnectionError("Socket error while sending message")

关于python - 在 Python 中处理异常的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/984526/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com