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异常值如何处理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334237.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言测试清单,c语言测试(C language test).doc

c语言测试(C language test)c语言测试(C language test)* * college course exam papersCourse Name: "C: the use of C language programming software to enter the world" (A) volumeGrade: class:Name: ______BUKAILI_________ number: _________________ test (…

mfc怎么获取进程的线程数_Python多线程获取小米应用商店App,看看我是怎么做到的

一、【项目背景】小米应用商店给用户发现最好的安卓应用和游戏,安全可靠&#xff0c;可是要下载东西要一个一个的搜索太麻烦了。而且速度并不是很快。今天小编就教大家利用多线程爬取小米应用商店的游戏模块&#xff0c;快速获取我们想要的软件安装包。二、【项目目标】目标 &a…

Linux Distribution Timeline for 2010(Linux 2010 年发行版时间线/族谱/发展图)

此图来自维基百科&#xff08;wikimedia&#xff09;&#xff0c;具体地址为&#xff1a;https://commons.wikimedia.org/wiki/File:Linux_Distribution_Timeline.svg?uselangzh-hans#filehistory

git强制推送_Git 常用命令

Git 常用命令总结1. GIT 工作区add commitworking directory ------- index(stage) ---------- HEAD | | | | | | 工作目录 暂存区 …

glacier2_Amazon Glacier的Scala客户端

glacier2Amazon Glacier是一项安全&#xff0c;耐用且成本极低的云存储服务&#xff0c;用于数据归档和长期备份。 Glacier提供了一种冷藏数据存档解决方案&#xff0c;这意味着已存储的数据不可立即检索。 您首先需要请求数据检索&#xff0c;访问时间可能从几分钟到几小时不等…

c 调用c语言dll数组,C#调用C类型dll入参为struct的问题详解

前言C# 可以通过 DllImport 的方式引用 C 类型的 dll。但很多 dll 的参数不会是简单的基础类型&#xff0c;而是结构体 struct 。因此就需要在 C# 端定义同样的结构体类型&#xff0c;才能实现调用 C 类型 dll。这里例举几种不同的结构体情况&#xff0c;以及其对应的解决方案。…

Slackware Linux 的发展历程

目前可供Linux用户使用的 发行版有很多种&#xff0c;它们虽基于共同的内核&#xff0c;但在安装、提供的应用程序、服务等方面各具特色&#xff0c;并拥有各自的用户群体。Slackware Linux是一个历史比较悠久的发行版&#xff0c;它的存在见证了Linux的发展历程&#xff0c;它…

golang 泛型_Golang 1.x版本泛型编程

本文介绍了Golang 1.x版本的泛型编程。往期回顾&#xff1a;浅谈动态追踪技术Go是一门天生为服务器程序设计的简洁的语言&#xff0c;因此Go的设计原则聚焦在可扩展性、可读性和并发性&#xff0c;而多态性并不是这门语言的设计初衷&#xff0c;因此就被放在了一边。虽然在2.0版…

jwt令牌_JWT令牌的秘密轮换

jwt令牌当您使用JSON Web令牌 &#xff08; JWT &#xff09;或需要对有效载荷信息进行签名或加密的任何其他令牌技术时&#xff0c;设置令牌的到期日期很重要&#xff0c;因此&#xff0c;如果令牌到期&#xff0c;则可以假定这可能被视为安全漏洞&#xff0c;您拒绝使用此令牌…

linux android build tools,build.gradle 文件中的 Android SDK Build Tools version

build.gradle 文件中的 Android SDK Build Tools versionAndroid,Gradle,SDK2018.07.17在 Android Gradle Plugin 3.0.1 中&#xff0c;最低的 Android SDK Build Tools 是 26.0.2&#xff0c;而我声明的 25.0.0 将被忽略掉。今天新建了一个 Android 项目的时候&#xff0c;无意…

Linux 常用的软件包管理器/软件包管理工具

文章目录RPMYUMDNFDPKGPacmanZypperPortageEopkgUrpmiRPM 代表系统&#xff1a;RHEL、CentOS、Fedora、openSUSE、SUSE企业版、PCLinuxOS、Mandriva Linux、Mageia 等 主命令&#xff1a;rpm YUM 代表系统&#xff1a;RHEL、CentOS 主命令&#xff1a;yum DNF 这是基于 RP…

怎样用C语言实现五子棋,C语言实现五子棋

可以称得上史上最简单的五子棋版本了。可以使用curses库来改进页面和下棋方式。并且对于输入的坐标没有进行鉴别&#xff0c;如果输入的坐标超过棋盘大小&#xff0c;就会段错误退出。我改进了一点&#xff0c;但是还是没有完全避免这个问题。/**Gobang.c*/#include#include#de…

jasperreports_JasperReports:棘手的部分

jasperreports如果您使用Java进行编程的时间足够长&#xff0c;则有可能需要为业务用户生成报告。 就我而言&#xff0c;我已经看到几个项目使用JasperReportsLibrary来生成PDF和其他文件格式的报告。 最近&#xff0c;我荣幸地观察了Mike和他的团队使用上述报告库以及他们所面…

电脑运行adb闪退_adb+python进阶使用

之前文章有提到过使用python加adb刷视频&#xff0c;今天带来进阶版——无线多台手机。首先要使用adb连接多台手机&#xff0c;手机和电脑肯定要在统一局域网内。1.打开手机开发者模式&#xff0c;并通过USB接口链接电脑。2.打开cmd&#xff1a;输入adb tcpip 5555, 会得到相关…

MacBook 强制关机的四种方法

文章目录一、强制关机二、强制断电三、安全关闭&#xff08;老款 MacBook&#xff09;四、强制关闭一、强制关机 长按电源键&#xff0c;5 秒左右 二、强制断电 ShiftControlOption电源键 三、安全关闭&#xff08;老款 MacBook&#xff09; ControlOptionCommand电源键。…

python存储和读取数据时出现错误_python读取json文件存sql及codecs读取大文件问题...

preface: 最近帮师兄处理json文件&#xff0c;需要读到数据库里面&#xff0c;以备其后续从数据库读取数据。数据是关于yelp网站里面的: https://github.com/Yelp/dataset-examples&#xff0c;http://www.yelp.com/dataset_challenge/. 涉及到一些json和sql的问题&#xff0c;…

Mac OS/macOS 关机的命令

文章目录一、立即关机二、10 分钟后关机三、晚上 8 点关机四、立即重启一、立即关机 sudo halt 或者 sudo shutdown -h now 二、10 分钟后关机 sudo shutdown -h 10 三、晚上 8 点关机 sudo shutdown -h 20:00 四、立即重启 sudo reboot 或者 sudo shutdown -r now

使用枚举映射_用EnumMaps映射枚举键

使用枚举映射这是一种在JDK中存在很长时间的类型&#xff0c;当我们要定义以枚举类型作为键的映射时&#xff0c;这种类型会派上用场&#xff1a; EnumMap是一种特殊的Map 。 我们将为给定的枚举创建一个映射&#xff1a; public enum CoffeeType {ESPRESSO, POUR_OVER, FREN…

linux 划ext4,linux – 有没有像ext4这样的’快速’格式?

严格的答案像-E lazy_itable_init这样的解决方案不会改变结果,只会加快进程.这是明确要求的,在许多情况下人们需要更多.额外奖励在大多数情况下,您实际上需要一些与您的使用模式匹配的选项,不仅可以加快文件系统的创建速度,还可以加快使用速度并增加可用空间.我刚做了一个测试.…