提问人:Richie Cotton 提问时间:2/3/2015 更新时间:12/5/2020 访问量:10901
我应该如何以及何时使用 on.exit?
How and when should I use on.exit?
答:
其优点是,无论是否抛出错误,都会在函数退出时调用。这意味着它的主要用途是在危险行为发生后进行清理。在这种情况下,有风险通常意味着访问 R 之外的资源(因此不能保证工作)。常见示例包括连接到数据库或文件(即使出现错误,在完成后也必须关闭连接)或将打印保存到文件(之后必须关闭图形设备)。on.exit
您还可以用于具有副作用的低风险行为,例如设置工作目录。on.exit
通常,应将 设置为 。请参见 https://adv-r.hadley.nz/functions.html?q=on.exit#on-exit。add = TRUE
on.exit()
使用on.exit
withr
包包含许多函数,这些函数可以更改设置、运行一些代码,然后更改设置。这些函数也出现在 devtools
包中。with_*
在后面
的包中可以找到另一种语法,其中是 的方便包装器,函数的工作方式与前面提到的包中的函数类似。defer
on.exit
scope_*
with_*
数据库连接
在此示例中,连接到 sqlite 数据库,确保
查询运行后,连接始终会关闭。数据库要求您在机器上安装 firefox,并且您可以
需要调整路径才能找到 cookie 文件。sqlite_get_query
cookies
library(RSQLite)
sqlite_get_query <- function(db, sql)
{
conn <- dbConnect(RSQLite::SQLite(), db)
on.exit(dbDisconnect(conn), add = TRUE)
dbGetQuery(conn, sql)
}
cookies <- dir(
file.path(Sys.getenv("APPDATA"), "Mozilla", "Firefox"),
recursive = TRUE,
pattern = "cookies.sqlite$",
full.names = TRUE
)[1]
sqlite_get_query(
cookies,
"SELECT `baseDomain`, `name`, `value` FROM moz_cookies LIMIT 20"
)
文件连接
在此示例中,wraps ,确保连接
阅读完成后,文件始终处于关闭状态。read_chars
readChars
read_chars <- function(file_name)
{
conn <- file(file_name, "r")
on.exit(close(conn), add = TRUE)
readChar(conn, file.info(file_name)$size)
}
tmp <- tempfile()
cat(letters, file = tmp, sep = "")
read_chars(tmp)
临时文件
以下改编自 CodeDepends 的示例使用临时文件来保存会话历史记录。一旦函数返回,就不需要此临时文件,因此会将其删除。
history_lines <- function()
{
f <- tempfile()
on.exit(unlink(f), add = TRUE)
savehistory(f)
readLines(f, encoding = "UTF-8")
}
保存基础图形
在此示例中,是一个使用 base 创建绘图的函数
图形。 接受一个函数和一个文件以将其保存到其中,用于确保图形设备始终处于关闭状态。my_plot
save_base_plot
on.exit
my_plot <- function()
{
with(cars, plot(speed, dist))
}
save_base_plot <- function(plot_fn, file)
{
png(file)
on.exit(dev.off(), add = TRUE)
plot_fn()
}
save_base_plot(my_plot, "testcars.png")
临时设置基本图形选项
在此示例中,调用 ,覆盖全局 gin par
ameter,用于在绘图完成后重置它。plot_with_big_margins
plot
mar
on.exit
plot_with_big_margins <- function(...)
{
old_pars <- par(mar = c(10, 9, 9, 7))
on.exit(par(old_pars), add = TRUE)
plot(...)
}
plot_with_big_margins(with(cars, speed, dist))
withr
/devtools
等效值:with_par
临时设置全局选项
在此示例中,是一个创建 . 确保创建的对象不包含显式因素。create_data_frame
data.frame
create_data_frame
create_data_frame <- function(){
op <- options(stringsAsFactors = FALSE)
on.exit(options(op), add = TRUE)
data.frame(x=1:10)
}
withr
/devtools
等效: with_options
等效:later
scope_options
其他例子
- 设置工作目录(,
withr::with_dir
later::scope_dir
) - 设置语言环境组件 (
withr::with_locale
) - 设置环境变量 (,
withr::with_envvars
later::scope_env_var
) - 设置库路径 (
withr::with_libpaths
) - 使用接收器重定向输出
- 临时加载包 (,
withr::with_package
withr::with_namespace
)
上一个:查找数据框的补码(反连接)
下一个:从字符串中删除反斜杠
评论