python异常值如何处理_如何处理异常

python异常值如何处理

最近,我与一个朋友进行了讨论,他是一个相对初级但很聪明的软件开发人员。 她问我有关异常处理的问题。 这些问题指出了一种技巧和窍门,肯定有它们的清单。 但是我坚信我们编写软件的方式背后的背景和动机,因此我决定从这样一个角度写关于异常的想法。
编程中的异常(使用Java作为故事的舞台)用于通知我们在执行代码期间发生了问题。 异常是类的特殊类别。 使它们与众不同的是,它们扩展了Exception类,而后者又扩展了Throwable类。 作为Throwable的实现,我们可以在必要时“抛出”它们。 那么,如何发生异常? 使用throw语句从JVM或代码段中引发异常类的实例。 那是怎么回事,但是为什么呢?

我敢肯定,当我们看到异常发生时,我们大多数人都会畏缩,但它们是我们受益的工具。 在引发异常之前,返回了特殊值或错误代码,以使我们知道操作没有成功。 忘记(或不知道)检查此类错误代码,可能会导致我们的应用程序发生不可预测的行为。 所以对

在我撰写以上内容时,我想到了两件事。 异常是一个不好的事件,因为创建异常时我们知道发生了问题。 异常是一种有用的构造,因为异常可以为我们提供有关发生错误的有价值的信息,并允许我们针对每种情况采取适当的行为。

试图散布此设计问题的实质: 触发方法/请求执行某项操作,但它可能会失败–我们如何最好地通知调用方它失败了? 我们如何传达有关发生的情况的信息? 我们如何帮助客户决定下一步该怎么做? 使用异常的问题在于我们“放弃了”,而不仅仅是“放弃”。 我们以“爆炸性”的方式来做,我们服务的客户/呼叫者必须处理混乱

因此,关于异常是我的第一条建议,因为它们是一件坏事,请尽量避免 。 在您所控制的软件部分中,实施难以出错的设计。 您可以使用支持此行为的语言功能。 我相信Java中最常见的异常是NullPointerException,而Optionals可以帮助我们避免它们。 让我们考虑一下我们想要检索具有指定id的雇员:

public Optional<Employee> tryGetEmployee(String employeeId) {
    return Optional.ofNullable(employeeService.getEmployee(employeeId));
}

现在好多了。 但是,除了我们语言的功能之外,我们还可以通过某种方式设计代码,以免发生错误。 如果我们考虑一种只能接收正整数作为输入的方法,则可以设置代码,这样客户端错误地传递无效输入的可能性就很小。 首先,我们创建一个PositiveInteger类:

public class PositiveInteger {
  private Integer integerValue;
 
  public PositiveInteger(Integer inputValue) {
     if(inputValue <= 0) {
        throw new IllegalArgumentException("PositiveInteger instances can only be created out of positive integers");
     }
    
     this.integerValue = inputValue;
  }
 
  public Integer getIntegerValue() {
     return integerValue;
  }
}

然后,对于只能使用正整数作为输入的方法:

public void setNumberOfWinners(PositiveInteger numberOfWinners) { … }

这些当然是简单的例子,我确实认为,问题的核心是偶尔出现问题,然后我们必须告知客户发生的情况。 假设我们从外部后端系统检索了一个员工列表,那么事情可能会出错。 如何处理呢?
我们可以将响应对象设置为GetEmployeesResponse,如下所示:

public class GetEmployeesResponse {
  private Ok ok;
  private Error error;

   …
  class Ok {
    private List<Employee> employeeList;
    ...
  }

  class Error {
    private String errorMessage;
    ...
  }
}

但是,让我们成为现实主义者,您无法控制代码库的每个部分,也不会更改所有内容。 确实会发生异常,因此,让我们从它们的简要背景信息开始。

如前所述,Exception类扩展了Throwable类。 所有异常都是异常类的子类。 可以将异常分为已检查和未检查的异常。 这仅表示某些异常(已检查的异常)要求我们在编译时指定在异常发生时应用程序的行为方式。 未检查的异常不要求我们进行编译时间处理。 要创建此类异常,您可以扩展RuntimeException类,该类是Exception的直接子类。 关于已检查与未检查的较旧的常见指导原则是,运行时异常用于表示应用程序通常无法预期或从中恢复的情况,而已检查异常是编写良好的应用程序应从中预期并从中恢复的情况。

好吧,我主张仅使用运行时异常 。 而且,如果我使用的库具有带检查异常的方法,则我将创建一个包装器方法,将其转换为运行时。 那为什么不检查异常呢? Bob叔叔在他的“ Clean Code”一书中指出, 它们违反了Open / Closed原理 ,因为使用新的throws声明更改签名可能会对调用该方法的程序的许多级别产生影响。

现在,无论是检查还是未检查,由于异常是一种结构,可让我们洞悉出了什么问题,因此应该对所发生的事情尽可能地具体和丰富 。 因此, 尝试使用标准异常,其他人将更容易理解发生的情况。 看到NullPointerException时,任何人都清楚原因。 如果您自己设置例外,请使其明智且具体。 例如,ValidationException使我知道某个验证失败,AgeValidationException将我指向特定的验证失败。 具体而言,既可以更容易地诊断出发生了什么,又可以根据发生的事情(异常类型)指定不同的行为。 这就是为什么您必须始终首先捕获最具体的异常的原因! 因此,这里出现了另一个常见建议,指示不要抓住“异常”。 这是一个有效的建议,我偶尔不遵循。 在我的api的边界(比如说我的REST服务的端点)中,我总是有通用的catch Exception子句。 我不希望任何意外以及我在代码中无法预测或防止的某些事情可能会向外界揭示事物。

具有描述性,但也可以根据抽象级别提供例外 。 考虑创建一个异常层次结构,以不同的抽象级别提供语义信息。 如果从程序的较低层引发了异常,例如与数据库相关的异常,则不必向API的调用者提供详细信息。 捕获异常并引发一个更抽象的异常,该异常仅通知调用者其尝试的操作失败。 这似乎与“仅在可能的情况下才捕获”的常见方法背道而驰,但事实并非如此。 只是在这种情况下,我们的“处理”是触发新异常。 在这些情况下,通过将原始异常传递给新异常的构造函数,可以使整个异常历史在抛出之间可用。

“手柄”一词已被多次使用。 这是什么意思? 当异常在我们熟悉的catch子句中被“捕获”时,被视为已处理。 引发异常时,首先它将在发生异常的代码中搜索异常处理,如果找不到异常,它将进入所包含方法的调用上下文,依此类推,直到找到异常处理程序或程序为止将终止。

我再次喜欢Bob叔叔的一件好事,就是try-catch-finally块定义了程序中的作用域。 除词汇范围外,我们还应考虑其概念范围,将try块视为事务 。 如果出问题了该怎么办? 我们如何确保使程序保持有效状态? 不要忽略例外! 我猜程序员对许多小时的不满是由无声异常引起的。 捕获并最终阻止是您进行清理的地方。 确保等待,直到掌握了正确处理异常的所有信息为止。 这可以与早起早发的原则联系在一起。 我们提早抛出,因此我们不必进行由于异常而不得不稍后恢复的操作,而为了及时掌握所有信息以正确处理异常,我们不必迟到。 顺便说一句,当您捕获异常时,只有在解决它们时才记录日志,否则单个异常事件会导致日志混乱。 最后,对于异常处理,我个人更喜欢创建一个可以在代码的不同部分中使用的错误处理服务 ,并在日志记录,重新抛出,清理资源等方面采取适当的措施。它集中了我的错误处理行为,避免了代码重复,并帮助我从更高级的角度了解应用程序中如何处理错误。

现在我们有了足够的上下文,悖论,规则及其例外,我们可以总结一下:

  • 尽量避免例外。 使用语言功能和适当的设计来实现它
  • 使用运行时异常,将方法与检查的异常包装在一起,然后将其转换为运行时
  • 尝试使用标准异常
  • 使您的例外情况具有特定性和描述性
  • 首先捕获最具体的异常
  • 不要赶上异常
  • 但是请在您的API边界上抓住Exception。 完全掌控一切
  • 创建与应用程序的层和功能匹配的异常层次结构
  • 在适当的抽象级别上抛出异常。 逐层移动时,捕获异常并引发更高级别的异常
  • 通过在新的构造函数中提供异常,在重新抛出时传递完整的异常历史记录
  • 将try-catch-finally块视为事务。 当出现问题时,请确保将程序保持在有效状态
  • 在可以处理时捕获异常
  • 永远不要有空的catch子句
  • 处理异常时记录异常
  • 拥有全局异常处理服务,并具有如何处理错误的策略

就是这样! 继续,要与众不同!

翻译自: https://www.javacodegeeks.com/2017/12/how-to-deal-with-exceptions.html

python异常值如何处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值