深入对比数据科学工具箱:Python和R的异常处理机制

概述

异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件)。Python和R作为一门编程语言自然也是有各自的异常处理机制的,异常处理机制在代码编写中扮演着非常关键的角色,却又是许多人容易混淆的地方。对于异常机制的合理运用是直接关系到码农饭碗的事情!所以,本文将具体介绍一下Python和R的异常处理机制,阐明二者在异常处理机制上的异同。

异常安全

在了解Python和R的异常机制之前,我们有必要了解一下异常安全的概念。

根据WikiPedia的文献,一段代码是异常安全的,如果这段代码运行时的失败不会产生有害后果,如内存泄露、存储数据混淆、或无效的输出。我们可以知道一段代码的异常安全通常分为下面五类:

异常安全通常分为5个层次:

  1. 失败透明:如果出现了异常,将不会对外进一步抛出该异常。(一般比较复杂)
  2. 强异常安全:可以运行失败,不过数据会回滚到代码运行前(无副作用)
  3. 基本异常安全:运行失败导致的数据变更,使得代码运行前后数据不一致了(有副作用)
  4. 最小异常安全:运行失败保存了无效数据,但是还不会引起崩溃,资源不会泄露(进程不会挂)
  5. 异常不安全:没有任何保证(进程可能会挂掉)

从上述的5个层次来看,我们可以知道,在平时写代码的时候,对数据库、文件、网络等的IO操作都是需要尽量保证无副作用的,也就是强异常安全。具体来说就是,RDBS操作在失败的时候需要回滚机制、所有IO操作在最后要保证IO连接资源关闭。

其实和多数语言的异常机制的语法是类似的:Python和R都是通过抛出一个异常对象或一个枚举类的值来返回一个异常;异常处理代码的作用域由try开始,以第一个异常处理子句(catch,

except等)结束;可连续出现若干个异常处理子句,每个处理特定类型的异常。最后通过finally子句,无论是否出现异常它都将执行,用于释放异常处理所需的一些资源。

下面将具体介绍二者的异常处理机制。

Python 中的异常处理机制

首先,Python 是一门面向对象语言,所有的异常类都是通过继承BaseException类来实现的,我们亦可以通过相应的继承来实现自定义的异常类,比如在工作流调度中使用AirflowException,具体实现可以直接看Airflow的源码。

事实上,这些在我们代码处理范围内的异常其实就是可以分成两个部分:

  1. IO异常:由网络抖动、磁盘文件位置变更、数据库连接变更等引起的IO异常问题。
  2. 运行期异常:由于计算或者传输的参数参数类型有误、参数值异常等等发生在运行期的异常,都统一被称为运行期异常。正常来说,IO上的异常我们都要有相应的try-catch-finally机制,在Python也就是如下实现:

  1. try: 
  2.    do something with IO 
  3. except: 
  4.    do something without IO 
  5. finally: 
  6.    close IO 

这里容易犯的一个错误就是在except中又引入了新的IO操作,比如在except中又引入了一个API的POST请求或者数据库写操作等等,这样如果在except阶段又发生了异常,将导致异常信息的丢失。

另一方面,对于可能的运行期异常则需要我们根据具体应用场景的需求来做相应的处理,一般就是遇到一个新的问题加一个新的异常捕获机制,当然这里也就考验到码农程序设计的功利,是否能够未雨绸缪。比如数组长度的检查,传入字典的Key检查等等。Python本身提供了丰富的异常处理类型并且易于拓展,正确使用将可以显著提升程序的鲁棒性(保住码农的饭碗)。

使用try-catch-finally机制是足够简单的,但是在混入return和rasie操作之后,事情就看起来变得有点复杂。

举一个例子:


  1. def test(): 
  2.     try: 
  3.         a = 1/0 
  4.     except: 
  5.         a = 0 
  6.         raise(ValueError,"value error, the division must greater than 0") 
  7.         return a 
  8.     finally: 
  9.         a = 1 
  10.         return a 
  11. test() 

你看这里的返回应该是什么呢?

其实,这里的返回最后应该是 1,而except中raise的异常则会被吃掉。这也是许多人错误使用finanlly的一个很好的例子。

Python在执行带有fianlly的子句时会将except内抛出的对象先缓存起来,优先执行finally中抛出的对象,如果finally中先抛出了return或者raise,那么except段抛出的对象将看起来被吃掉了。

一个段正确的处理方式应该是这样的:


  1. try: 
  2.     do IO 
  3.     info = {"status":200} 
  4. except: 
  5.     info = {"status":400} 
  6. finally: 
  7.     try: 
  8.         write log(info) 
  9.     except: 
  10.         raise(SomeError,"error message") 
  11.     close IO 

具体的调用栈的过程可以参考这个更加生动的例子:

R 中的异常处理机制

R和Python最大的不同就是 R 本质上是一门强动态类型的非纯函数式编程语言(所谓非纯即存在副作用)而非面向对象语言。从函数式编程语言的角度上讲,R和Erlang、LISP的关系比较近一些。

既然是函数式语言,处理异常也是通过函数式的,而非直接通过面向对象的方式。R 从语法上来看就略显突兀(花括号函数式语言的一大通病):


  1. tryCatch({ 
  2.   doStuff() 
  3.   doMoreStuff() 
  4. }, some_exception = function(se) { 
  5.   recover(se) 
  6. }) 

如果这段用Python来表达就变成:


  1. try: 
  2.   doStuff() 
  3.   doMoreStuff() 
  4. except SomeException, se: 
  5.   recover(se) 

事实上正确运用 R 的异常处理机制反而是比较负担小的一种方式:(R 还支持用中文字符集命名变量)


  1. tryCatch({ 
  2.   结果 <- 表达式 
  3. }, warning = function(w) { 
  4.     warning() 
  5.   ... # 运行期异常 
  6. }, error = function(e) { 
  7.     stop() 
  8.   ... # IO异常 
  9. }, finally { 
  10.     on.exit() 
  11.   ... # 资源回收 

下面是 Hadley 大神对R的异常处理机制优点的分析:

One of R’s great features is its condition system. It serves a
similar purpose to the exception handling systems in Java, Python, and
C++ but is more flexible. In fact, its flexibility extends beyond error
handling–conditions are more general than exceptions in that a
condition can represent any occurrence during a program’s execution
that may be of interest to code at different levels on the call stack.
For example, in the section “Other Uses for Conditions,” you’ll see
that conditions can be used to emit warnings without disrupting
execution of the code that emits the warning while allowing code higher
on the call stack to control whether the warning message is printed.
For the time being, however, I’ll focus on error handling.

The condition system is more flexible than exception systems because
instead of providing a two-part division between the code that signals
an error and the code that handles it, the condition system splits the
responsibilities into three parts–signaling a condition, handling it,
and restarting. In this chapter, I’ll describe how you could use
conditions in part of a hypothetical application for analyzing log
files. You’ll see how you could use the condition system to allow a
low-level function to detect a problem while parsing a log file and
signal an error, to allow mid-level code to provide several possible
ways of recovering from such an error, and to allow code at the highest
level of the application to define a policy for choosing which
recovery strategy to use.

我的理解是R通过条件机制,然我们可以选择性的在低阶函数中把warning吃掉,这样就不至于影响高阶函数的运行?条件机制将异常分为三阶段而不是两阶段:

  1. 异常信号捕获
  2. 异常处理
  3. 重启机制。

并且我们还可以看到在异常处理中,如何在中阶函数中恢复低阶函数的Error,并且在高阶函数中选择一定的恢复策略。

这段貌似个人理解有误,还请看官指正。

作者:HarryZhu

来源:51CTO

时间: 2024-09-20 01:11:06

深入对比数据科学工具箱:Python和R的异常处理机制的相关文章

《数据科学实战手册(R+Python)》一第2章 汽车数据的可视化分析(R)

第2章 汽车数据的可视化分析(R) 数据科学实战手册(R+Python) 本章涵盖如下内容. 获取汽车燃料效率数据 为了你的第一个项目准备好R 将汽车燃料效率数据导入R 探索和描述燃料效率数据 进一步分析汽车燃料效率数据 研究汽车的产量以及车型 简介 本书介绍的第一个项目是分析汽车燃料经济数据.我们首先用R对该数据集进行分析.R常常被称为数据科学通用语言,因为它是目前最流行的统计和数据分析语言.在本书前半部分的各个章节中,你将会看到R在数据处理.建模.可视化方面的过人之处,并开发一些有用的脚本,

《数据科学实战手册(R+Python)》一第1章 准备你的数据科学环境

第1章 准备你的数据科学环境 数据科学实战手册(R+Python)本章涵盖如下内容: 理解数据科学管道 在Windows.Mac OS X和Linux上安装R 在R和RStudio中安装扩展包 在Linux和Mac OS X上安装Python 在Windows上安装Python 在Mac OS X和Linux上安装Python数据分析库 安装更多Python包 安装和使用virtualenv 简介传统意义上的食谱,就是作者擅长的烹饪菜谱,用于帮助读者学习新菜的做法.很多人相信,对于一份食谱而言,

《数据科学实战手册(R+Python)》一导读

前 言 数据科学实战手册(R+Python)我们生活在数据时代.每一年,数据都在大量快速地增长,因此分析数据和从数据中创造价值的需求也比以往任何时候都更为重要.那些知道如何使用数据以及如何用好数据的公司,在后续的竞争中会比那些无法使用数据的公司更有优势.基于此,对于那些具备分析能力,能够从数据中提取有价值的洞见,并且将这些洞见用于实践产生商业价值的人才的需求会放大. 本书提供了多种令读者能够学习如何从数据创造价值的机会.书中所用的数据来自很多不同的项目,而这些项目可以体现出最新的数据科学项目的各

2017数据科学职位报告:R超过SAS

文章讲的是2017数据科学职位报告:R超过SAS,招聘广告的数量能一定程度上反应每一种软件的流行程度,并从中预测出哪一种在将来会更加流行.本文作者以美国最大的招聘网站Indeed.com为统计平台,通过对某一天数据科学职位的招聘数量进行统计分析,得出数据科学软件的变化趋势. 为了公平,本文采用了一种专门的方法,用来在数据科学职位范围内统计每种软件的招聘数量,文中所有的图片也都是在这个前提下取得的,统计日期为2017年2月24日. 正文 各种软件招聘量见下图.其中最多的是SQL,将近18000,然

2017数据科学职位报告:R超过SAS,但仍不如Python

更多深度文章,请关注:https://yq.aliyun.com/cloud Bob Muenchen <R for SAS and SPSS Users>的作者,r4stats.com(分析数据科学软件趋势.帮助人们学习R语言的一家网站)的创办者:同时也是ASA官方认证的专业统计学家(30年从业经验),现任田纳西大学OIT Research Computing Support的管理员. 前言 招聘广告的数量能一定程度上反应每一种软件的流行程度,并从中预测出哪一种在将来会更加流行.本文作者以美

第二热门语言:从入门到精通,Python数据科学简洁教程

Python是一门通用的编程语言,在过去十年中被数据科学领域广泛使用.事实上,Python在数据科学领域是仅次于R的第二热门的编程语言. 本篇文章的主要目的在于向大家展示使用Python学习数据科学有多么的容易.你可能以为自己要先成为一名高级Python程序员,然后才能进行通常与数据科学相关的复杂任务,然而事实并非如此.Python附带了很多有用的工具库,它们可以在后台为你提供强大的支持.你甚至不需要知道程序在运行什么,你不必关心这些.唯一你真正需要知道的是,你需要执行一些特定的任务,而Pyth

研究了数千个在线课程,我整理了一份数据科学入门课清单

一年前,我退出了加拿大最好的计算机科学项目之一,利用在线资源开始创建属于自己的数据科学硕士课程.我意识到我可以通过edX, Coursera,以及Udacity学习我所需要的一切,而且学的更快.效率更高,学费更低. 数据可视化:Alanah Ryding 现在我差不多快要完成了.我上了很多数据科学相关的课程,旁听过更多课程的部分内容.我知道对于一个准备成为数据分析师或数据科学家的初学者来说有哪些选择,以及什么样的技能是必需的.几个月前,我开始创建一个用评价驱动的指南,用来为数据科学中的每个主题推

关于数据科学的那些事

更多深度文章,请关注云计算频道:https://yq.aliyun.com/cloud 请收下这份关于人工智能的根目录--博客整理系列(一) 关于数据科学的那些事--博客整理系列(二) 机器学习必备手册--博客整理系列(三) 扩展眼界的都在这--博客整理系列(四) 深度学习必备手册(上)--博客整理系列(五) 深度学习必备手册(下)--博客整理系列(六) 随着科技的发展,人类社会拥有数据的规模增长很快,每时每刻.从天到地都有大量数据被产生和存储下来.这些数据被积累下来,到底怎么样使用才能创造出我

大数据到底怎么学:数据科学概论与大数据学习误区

"数据科学家走在通往无所不知的路上,走到尽头才发现,自己一无所知."-Will Cukierski,Head of Competitions & Data Scientist at Kaggle 最近不少网友向我咨询如何学习大数据技术?大数据怎么入门?怎么做大数据分析?数据科学需要学习那些技术?大数据的应用前景等等问题.由于大数据技术涉及内容太庞杂,大数据应用领域广泛,而且各领域和方向采用的关键技术差异性也会较大,难以三言两语说清楚,本文从数据科学和大数据关键技术体系角度,来说