本文介绍了我应该如何以及何时使用on.exit?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

on.exit 在函数退出时调用代码,但是应该如何以及何时调用我用吗?

on.exit calls code when a function exits, but how and when should I use it?

推荐答案

on.exit的优点在于,无论是否抛出错误,该函数退出时都会被调用..这意味着它的主要用途是在发生危险行为后进行清理.在这种情况下,冒险通常意味着访问R之外的资源(因此不能保证可以正常工作).常见的示例包括连接到数据库或文件(即使出现错误也必须在完成后关闭连接),或将绘图保存到文件(此后必须关闭图形设备).

The advantage of on.exit is that is gets called when the function exits, regardless of whether an error was thrown. This means that its main use is for cleaning up after risky behaviour. Risky, in this context, usually means accessing resources outside of R (that consequently cannot be guaranteed to work). Common examples include connecting to databases or file (where the connection must be closed when you are finished, even if there was an error), or saving a plot to a file (where the graphics device must be closed afterwards).

您还可以将on.exit用于具有副作用的低风险行为,例如设置工作目录.

You can also use on.exit for low-risk behaviour with a side effect, such as setting a working directory.

withr 程序包包含许多with_*函数,这些函数可更改设置,运行某些代码,然后改回设置.这些功能也出现在 devtools 包中.

The withr package contains many with_* functions that change a setting, run some code, then change the setting back. These functions also appear in the devtools package.

later 包中找到了另一种语法,其中deferon.exitscope_*函数的作用类似于前面提到的软件包中的with_*函数.

An alternate syntax is found in the later package where defer is a convenience wrapper to on.exit, and scope_* functions work like the with_* functions in the previously mentioned packages.

在此示例中,sqlite_get_query连接到sqlite数据库,确保在查询运行后,连接总是关闭. cookies数据库要求您在计算机上安装了Firefox,并且您可能需要调整路径以查找cookie文件.

In this example, sqlite_get_query connects to an sqlite database, ensuringthat the connection always gets closed after the query has run. The cookiesdatabase requires that you have firefox installed on your machine, and you mayneed to adjust the path to find the cookies file.

library(RSQLite)
sqlite_get_query <- function(db, sql)
{
  conn <- dbConnect(RSQLite::SQLite(), db)
  on.exit(dbDisconnect(conn))
  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"
)


文件连接

在此示例中,read_chars包装readChars,确保连接读取完成后,文件始终关闭.


File connections

In this example, read_chars wraps readChars, ensuring that the connectionto the file is always closed after reading is finished.

read_chars <- function(file_name)
{
  conn <- file(file_name, "r")
  on.exit(close(conn))
  readChar(conn, file.info(file_name)$size)
}

tmp <- tempfile()
cat(letters, file = tmp, sep = "")
read_chars(tmp)


临时文件

下面的示例改编自 CodeDepends ,该示例使用临时文件来保存会话历史记录.函数返回后就不需要此临时文件,因此将其删除.


Temporary files

The following example adapted from CodeDepends uses a temporary file to save the session history. This temporary file is not needed once the function returns so it is removed.

history_lines <- function()
{
  f <- tempfile()
  on.exit(unlink(f))
  savehistory(f)
  readLines(f, encoding = "UTF-8")
}


保存基本图形

在此示例中,my_plot是使用基数创建图的函数图形. save_base_plot接受一个函数和一个文件以将其保存到on.exit确保图形设备始终处于关闭状态.


Saving base graphics

In this example, my_plot is a function that creates a plot using basegraphics. save_base_plot accepts a function and a file to save it to, usingon.exit to ensure that the graphics device is always closed.

my_plot <- function()
{
  with(cars, plot(speed, dist))
}

save_base_plot <- function(plot_fn, file)
{
  png(file)
  on.exit(dev.off())
  plot_fn()
}

save_base_plot(my_plot, "testcars.png")


临时设置基本图形选项

在此示例中,plot_with_big_margins调用plot,覆盖全局mar gin par 仪表,在绘制完成后使用on.exit将其重置.


Setting base graphics options temporarily

In this example, plot_with_big_margins calls plot, overriding the global margin parameter, using on.exit to reset it after the plot is completed.

plot_with_big_margins <- function(...)
{
  old_pars <- par(mar = c(10, 9, 9, 7))
  on.exit(par(old_pars))
  plot(...)
}

plot_with_big_margins(with(cars, speed, dist))

withr/devtools等效项: with_par

withr/devtools equivalent: with_par

在此示例中,create_data_frame是创建data.frame的函数. create_data_frame确保创建的对象不包含显式因素.

In this example, create_data_frame is a function that creates a data.frame. create_data_frame ensures that the created object doesn't contain explicit factors.

create_data_frame <- function(){
  op <- options(stringsAsFactors = FALSE)
  on.exit(options(op))

  data.frame(x=1:10)
}

withr/devtools等效项: with_options
later等效项:scope_options

withr/devtools equivalent: with_options
later equivalent: scope_options

这篇关于我应该如何以及何时使用on.exit?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

查看更多