on.exit
calls code when a function exits, but how and when should I use it?
上。當一個函數退出時,退出調用代碼,但是如何以及何時應該使用它?
42
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).
上的優勢。退出是在函數退出時調用,不管是否拋出錯誤。這意味着它的主要用途是在危險行為之后進行清理。在這種情況下,風險通常意味着訪問R之外的資源(因此不能保證工作)。常見的例子包括連接到數據庫或文件(當您完成時,連接必須被關閉,即使出現錯誤),或者將一個情節保存到一個文件(在此之后,圖形設備必須關閉)。
You can also use on.exit
for low-risk behaviour with a side effect, such as setting a working directory.
你也可以用on。低風險行為的退出,有副作用,例如設置工作目錄。
on.exit
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.
withr包包含許多具有更改設置、運行一些代碼、然后更改設置的函數。這些函數也出現在devtools包中。
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.
在后面的包中發現了另一種語法,在這個包中,延遲是一個方便的包裝。exit和scope_*函數像前面提到的包中的with_*函數一樣工作。
In this example, sqlite_get_query
connects to an sqlite database, ensuring that the connection always gets closed after the query has run. The cookies
database requires that you have firefox installed on your machine, and you may need to adjust the path to find the cookies file.
在本例中,sqlite_get_query連接到一個sqlite數據庫,確保在查詢運行后連接總是被關閉。cookie數據庫要求您的機器上安裝了firefox,您可能需要調整路徑以找到cookie文件。
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"
)
In this example, read_chars
wraps readChars
, ensuring that the connection to the file is always closed after reading is finished.
在本例中,read_chars包裝了readChars,確保在讀取完成后,該文件的連接始終是關閉的。
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)
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.
下面的例子來自CodeDepends,它使用一個臨時文件來保存會話歷史。這個臨時文件在函數返回時不需要,因此它被刪除。
history_lines <- function()
{
f <- tempfile()
on.exit(unlink(f))
savehistory(f)
readLines(f, encoding = "UTF-8")
}
In this example, my_plot
is a function that creates a plot using base graphics. save_base_plot
accepts a function and a file to save it to, using on.exit
to ensure that the graphics device is always closed.
在這個例子中,my_plot是一個使用基本圖形創建繪圖的函數。save_base_plot接受一個函數和一個文件來保存它,並使用它。退出,以確保圖形設備始終關閉。
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")
In this example, plot_with_big_margins
calls plot
, overriding the global mar
gin par
ameter, using on.exit
to reset it after the plot is completed.
在本例中,plot_with_big_margin調用plot,覆蓋全局邊界參數,使用on。退出,在情節完成后重新設置。
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
equivalent: with_par
withr / devtools等效:with_par
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是一個創建數據的函數。create_data_frame確保創建的對象不包含顯式的因素。
create_data_frame <- function(){
op <- options(stringsAsFactors = FALSE)
on.exit(options(op))
data.frame(x=1:10)
}
withr
/devtools
equivalent: with_options
later
equivalent: scope_options
withr/devtools等價:with_options稍后等效:scope_options。
withr::with_dir
, later::scope_dir
) withr::with_locale
) withr::with_envvars
, later::scope_env_var
) withr::with_libpaths
) 本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2015/02/03/720b66cc7c81626d710534bb3ff3d7ff.html。