异常处理——R与Python

本文将简单介绍R和Python中常用的异常处理方式。

R

R中常用trytryCatch

try

如果只是为了某段代码不影响后续脚本的执行,最简单的办法就是直接在外层套上try()

# 如果该语句失败也没关系,那么可以直接用偷懒的写法:try
print('-- 开始 --')
try(o <- 'error'+2) # 会输出报错,但是程序不会停止,接下来的代码可以继续运行
print('-- 结束 --')
# [1] "-- 开始 --"
# Warning message:
# In strsplit(code, "\n", fixed = TRUE) :
  # input string 1 is invalid in this locale
# Error in "error" + 2 : non-numeric argument to binary operator
# [1] "-- 结束 --"

trycatch

最常见的异常处理函数是tryCatch,能够让代码更加flexible

简单示例:
  • 'error'+2报错
  • 错误记录在e中 并打印
  • 报错后,对应变量 o 被赋值为3
tryCatch({o <- 'error'+2}, error = function(e) print(e), call = (o <- 3))
print(o)
# [1] 3
call的使用

为了防止一段代码出错,保证后续继续运行,并记录具体出错的位置,可以结合 call 使用

error_ls <- c()
i <- 0
for(x in c(-2:2)){
    i <- i+1
    tryCatch(
        expr={x1 <- ifelse(x>0, x, "make error") + 1
        error_ls[i] <- 'success'
        },
        error = function(e){
            cat('Error: ', e$message, 'index: ',i,'\n')}, 
        call = (
            # 如果报错,则对 x1 和 error_ls 重赋值
            {x1 <- 100
            error_ls[i] <- 'error'}))
    cat('x1: ',x1,'\n')
}

x<=0时都会报错,并给x1重赋值为100,x>0时则正常运行

# Error:  non-numeric argument to binary operator index:  1 
# x1:  100 
# Error:  non-numeric argument to binary operator index:  2 
# x1:  100 
# Error:  non-numeric argument to binary operator index:  3 
# x1:  100 
# x1:  2 
# x1:  3 

error_ls已记录对应每次循环的正误

print(error_ls)

注:call函数会优先执行expr的内容,如果执行失败,则执行call内部的语句,但若call内部出现其它赋值语句,则始终会被执行(会认为expr中没有相应返回),例如:

error_ls2 <- c()
i <- 0
for(x in c(-2:2)){
    i <- i+1
    tryCatch(
        expr={1+1},
        call = (
            # 对expr中不包含的变量赋值,每次都会执行
            {error_ls2[i] <- 'error'}))
}

即时没有任何异常,依然会执行error_ls2[i] <- 'error'

print(error_ls2)
# [1] "error" "error" "error" "error" "error"
包装成函数

包装成函数,不使用循环,转为在 data.table中快速运行

# 写一个会遇到错误的函数
process <- function(x){
    # 显然,x<=0时,'make error'+1 字符串和数值不能相加,该函数会报错
    ifelse(x>0, x, "make error") + 1
}

# 嵌套异常处理后的函数
process_tryCatch <- function(x){
    tryCatch(expr=process(x), 
             error=function(e) {
                 # 如果报error,则输出对应报错,并直接返回 -1001
                 cat('Error: ', e$message, ". Input: ", x, "\n")
                 # 此处不再需要call,可以直接在error里写return
                 return(-1001)
             }
    )
}

构造个简单的data.table, 对a列的每个元素做process运算

library(data.table)
df = data.table(a=-2:2)
df[, new_a := process_tryCatch(a),a]
# Error:  non-numeric argument to binary operator . Input:  -2 
# Error:  non-numeric argument to binary operator . Input:  -1 
# Error:  non-numeric argument to binary operator . Input:  0

对于>0的会正常返回,其他返回tryCatch设置的 -1001

df
    # a new_a
# 1: -2 -1001
# 2: -1 -1001
# 3:  0 -1001
# 4:  1     2
# 5:  2     3

Python

try-except

try-except是python中常用异常处理方式,如果try语句块中发生异常,则执行except语句块(捕获异常并处理)。示例如下

import sys 
try:
    re = "error" + 2
except Exception as e: 
    s = sys.exc_info()
    print('Error: %s; line:[%s]' % (str(e), s[2].tb_lineno))
  • sys.exc_info() 记录错误出现的位置(问题回溯)
  • Exception as e 记录具体的报错信息。

以上示例运行结果如下:

# Error: cannot concatenate 'str' and 'int' objects; line:[3]

Tips

本文为博主从自己的github主页复制迁移至此,原文链接在博客 https://hetal-cq.github.io/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值