【发布时间】:2020-12-17 09:09:46
【问题描述】:
如果你定义函数,它们默认都是Global Environment 的一部分。
我想知道,是否有办法将函数的父环境设置为调用环境(而
运行时 - 一个函数可能在不同的地方被调用!)。因此,在嵌套函数的情况下,
它应该成为可能,只在一个环境中定义一个变量,我希望有一个像
fun1 <- function() {
# variable "my_env" defined only in this environment
subfun() # calls subsubfun()
return(NULL)
}
exists("my_env", different_environments) 的输出喜欢
# [1] "fun1"
# [1] "===="
# [1] TRUE # Only here: "here", in this function
# [1] FALSE
# [1] FALSE
# [1] " subfun"
# [1] " ======"
# [1] FALSE
# [1] TRUE # Only here: "parent environment", in calling function
# [1] FALSE
# [1] " subsubfun"
# [1] " ========="
# [1] FALSE
# [1] FALSE
# [1] TRUE # Only here: "parent-parent environment", in the function calling the function
来自文档?parent.frame
sys.parent 如果 n 为 1,则返回父框架的编号( 默认),如果 n 为 2,则为祖父母,依此类推。另见“注”。
(...) parent.frame(n) 是 sys.frame(sys.parent(n)) (实现效率稍高)。注意
严格来说,sys.parent 和 parent.frame 指的是上下文 父解释函数。所以内部功能(可能或 可能不会设置上下文,因此可能会或可能不会出现在调用堆栈上) 可能不算数,S3 方法也能做出令人惊讶的事情。 注意惰性求值的效果:这两个函数看 评估它们时的调用堆栈,而不是它们的时间 被称为。将调用作为函数参数传递给它们不太可能 是个好主意。
从here 开始的一些示例,它不起作用,因为所有函数都是全局环境的一部分。
subfun0 <- function() {
e <- parent.frame()
attr(e, "name") <- "my_env"
assign("my_env", 1,
envir = parent.frame(),
inherits = FALSE, immediate = TRUE)
return(NULL)
}
subsubfun <- function() {
print(" subsubfun")
print(" =========")
print(exists("my_env"))
print(exists("my_env", parent.frame()))
env <- parent.frame()
print(exists("my_env", parent.env(env)))
return(NULL)
}
subfun <- function() {
print(" subfun")
print(" ======")
print(exists("my_env"))
print(exists("my_env", parent.frame()))
env <- parent.frame()
print(exists("my_env", parent.env(env)))
subsubfun()
return(NULL)
}
fun1 <- function() {
print("fun1")
print("====")
subfun0()
print(exists("my_env"))
print(exists("my_env", parent.frame()))
env <- parent.frame()
print(exists("my_env", parent.env(env)))
subfun()
return(NULL)
}
fun1()
(我刚刚意识到,我对“调用环境”的理解完全错误,我的问题是,我能否让“我的图片”在 R 中工作。)
【问题讨论】:
-
我不明白你为什么需要它。为什么你不能只将参数传递给你的函数?或者为什么不将环境作为参数传递?
-
@Edo 我想跟踪特殊变量而不需要重写每个函数。我认为这会增加一些很好的灵活性。具体触发是this 非常好的问题...
-
追踪..?你的意思是? ps:
environment<-改变一个函数的环境呢? es:a<-function()ib<-function(){i<-1;a()};b()返回错误d<-function(){environment(a)<-environment();i<-1;a()};d()返回 [1] 1 -
通过“track”你的意思是你想看看在几个函数之间传递的变量的值是如何随时间变化的?
-
@Edo 你是对的,“跟踪”是误导,我的意思是你可以创建一个变量,你知道“一直”,如果它存在,它必须存在于某个环境中和一个特定的名字。我试过
environment() <- rlang::caller_env(),但没有成功。而来自here,我也不确定我的计划是不是不可能了。