作者Wush978 (拒看低质媒体)
看板R_Language
标题[心得] R 的例外处理
时间Thu Apr 4 23:45:03 2013
[关键字]: R, 例外处理, exception
[重点摘要]: 简单的分享我对於R 的例外处理相关的心得
R 的官方文件在[Exception
handling](
http://cran.r-project.org/doc/manuals/R-lang.html#Exception-handling)
有介绍R的例外处理机制。
这里我简单介绍如何在R写出类似java、c++或python等主流语言所使用的try-catch机制
。
另外这里讲的都是以R2.15为主。
# 错误相关的函数
- `warning(...)`: 抛出一个警告
- `stop(...)`: 抛出一个例外
- `surpressWarnings(expr)`: 忽略`expr`中发生的警告
- `try(expr)`: 尝试执行
- `tryCatch`: 最主流语言例外处理的方法
- `conditionMessage` : 显示错误讯息
# R 和其他主流语言的不同
R 语言处理例外的方式,是透过函数,而非像其他主流语言使用try ... catch ... 等语
法。这是因为R 语言几乎所有功能都是用函数来实作的。请参考[Every operation is a
function
call](
https://github.com/hadley/devtools/wiki/Functions#every-operation-is-a-function-call)
。
# 一个`try`的范例
我自己最早是先发现`try`函数。`try`的用法近似於回传expr的结果*或*执行时发生的错
误。
```r
result <- try(..., silent=TRUE)
if (class(result) == "try-error") {
... # 错误处理
}
```
由於R是我第一个语言,所以我也就接受他了。直到我後来发现主流语言的try -- catch
机制後,才觉得奇怪。
# 一个`tryCatch`的范例
後来我发现`tryCatch`函式提供了比较类似try -- catch机制的错误处理方法。
```r
tryCatch({
result <- expr
}, warning = function(w) {
... # 警告处理
}, error = function(e) {
... # 错误处理
}, finally {
... # 清理
}
```
这种语法和其他主流语言的机制比起来接近多了。
# `conditionMessage`
有时候当错误发生时,我无法处理,需要直接回传错误讯息给使用者时,或是log起来时
,我们可以在`tryCatch`中使用`conditionMessage`来撷取错误讯息。
```r
tryCatch({
stop("demo error")
}, error = function(e) {
conditionMessage(e) # 这就会是"demo error"
})
```
# 错误处理的相关issue
就我的经验来说,写出一个稳健的程式码是非常不容易的。在软体工程中有许多文章介绍
如何写出这类程式码。
大部份R 写出来的script都是只用一次的,所以程式稳定不稳定就不是重点,也因此大家
都很少去使用R 的例外处理机制。
某些R 使用者,会需要写出自动化的script。而这时候为了要让回圈不中断,使用者才开
始使用例外处理。
但是当写到套件时,例外处理就很重要了。这时候,函数的使用者将不再是开发者自己,
而还包括其他的使用者,甚至是其他的开发者。此时例外处理就变成一门哲学了。这部份
我也只略懂皮毛,下面只列出少许我知道的issue:
- 释放资源: 由於错误发生时,函数会在不正常的地方退出,所以此时需要释放一些函数
中获得的资源(如资料库连线需要关闭)。这部份在C++可以用
[RAII](
http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)等
技术来保证资源不会被忘记释放。然而在R中,我还不知道有什麽类似的安全机制。
- exception safety guarantees: 当使用者要基於某些函数建立复杂的程式时,通常希
望这些函式是不会出错的。[Exception
safety](
http://en.wikipedia.org/wiki/Exception_safety)就是在探讨相关的issue。
毕竟使用的函数有例外状况时,原本的函数也跟着会有例外状况。就像是盖在危楼上的楼
层,一定也很危险一样。目前我也尚未看过R在这部份的功能。
- 错误讯息: 当错误发生时,提供的错误讯息是否能帮助使用者找到发生错误的理由。R
在这部份也很不足,这造成要除错R的程式时,没有相当的经验,是无法理解错误讯息的
。
# 参考资料
- [Exception
handling](
http://cran.r-project.org/doc/manuals/R-lang.html#Exception-handling)
- [Using R — Basic error Handing with
tryCatch()](
http://mazamascience.com/WorkingWithData/?p=912)
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 36.228.124.114
1F:推 johnsonla:大推这篇!!! 整个受用:P 04/04 23:48
2F:→ clickhere:gc() 可以释放 R 的 memory. 但外部呼叫的部份crash, 就 04/05 02:34
3F:→ clickhere:不是R能掌握的. 所以要自己去 free 了. 但如果是由 R 04/05 02:35
4F:→ clickhere:allocated 的部份, gc() 还是可以释放的. 04/05 02:36
5F:→ clickhere:try or tryCatch 是很耗资源的. 本身就是 function call 04/05 02:37
6F:→ clickhere:call了, 它们自建一个 environment 另外去执行了. 04/05 02:38
7F:→ andrew43:好文! 有用! 04/08 10:11