在R中访问函数的执行环境
我有一个为程序的其余部分“准备”东西的功能。例如,以下函数定义了两个函数:在R中访问函数的执行环境,r,function,environment,execution,R,Function,Environment,Execution,我有一个为程序的其余部分“准备”东西的功能。例如,以下函数定义了两个函数: prepare = function() { f = function(x) x+1 g = function(x) x+2 } 当然,一旦函数执行,函数f和g就不再可用。它们是在“prepare”的执行环境中定义的,一旦函数完成执行,它就消失了 我的问题是,有没有办法保持或访问该执行环境 这种情况是,我从外部获取“prepare”函数,因此无法编辑其代码,我希望以以下方式执行它并使用它所做的任何事情:
prepare = function() {
f = function(x) x+1
g = function(x) x+2
}
当然,一旦函数执行,函数f和g就不再可用。它们是在“prepare”的执行环境中定义的,一旦函数完成执行,它就消失了
我的问题是,有没有办法保持或访问该执行环境
这种情况是,我从外部获取“prepare”函数,因此无法编辑其代码,我希望以以下方式执行它并使用它所做的任何事情:
my_function = function(prepare) {
# the prepare function is supplied by the user
prepare() #this should define the f and g functions as above
f(3) # this wouldn't work normally, since f is defined inside prepare
}
有没有办法做到这一点?也就是说,使“prepare”影响调用环境,而不是其执行环境
编辑:
找到了一个使用body()的变通方法,它允许访问函数内部的表达式,并从中构建新的表达式,因此我基于“prepare”函数和“original”函数的“body”构建了一个新函数。正如我所想,真正的解决办法是使用“面向方面”。但不幸的是,R不是面向方面的语言。可能是一个新软件包的想法:-)如果您稍微修改一下
prepare
函数:
prepare = function() {
f = function(x) x+1
g = function(x) x+2
return(list(f,g))
}
您可以访问如下功能:
prepare()[[1]](25)
# [1] 26
或者您可以使用
使用environment(fun)
返回函数的封闭环境(定义函数如何查找对象)这一事实,下面使用environment()
可以访问prepare()
中定义的函数:
这将产生:
Result of calling function f(3) defined in function prepare(): 4
Result of calling function g(3) defined in function prepare(): 5
但是,这仅是因为函数prepare()
返回一个函数(在本例中,函数g()
,该函数在prepare()
的最后一行定义并因此返回),这意味着对prepare()
返回的对象的environment()
调用(\u prepare
返回的fun\u)检索prepare()
中定义的函数g()
的封闭环境,它恰好是prepare()
的执行环境
如果prepare()
的返回值不是函数,则上述代码不再有效
另一方面,如果您可能有其他应用程序,那么下面的内容会很方便:我编写了一个名为的包,它允许您通过函数名检索函数的执行环境(get\u fun\u env()
)。但是,为了使其正常工作,该函数必须是调用get\u fun\u env()
的调用堆栈的一部分,不幸的是,在上面的示例中并非如此。如我所说,我无法编辑“prepare”函数。它是由其他人编写的,并作为我的代码的参数提供。因此您的建议不适用。您如何确保其他人的函数中包含f
和g
?同样,您可以要求他们返回列表或更改范围或..编写f
和g
在一个单独的文件中,然后您可以调用myEnvsee my edit。最终,我使用body()找到了一个解决方法。在我的场景中,由用户提供“prepare”函数以及稍后在代码中使用它的方法,但代码必须在我创建的环境中执行(并向其中添加更多用户无法控制的内容)。不幸的是,我无法更改“prepare”函数,该函数由其他人提供并作为参数传递。
>prepare<-function() return(list(f=function(x) x+1, g=function(x) x+2))
> p<-prepare()
> p$f(1)
[1] 2
> p$g(1)
[1] 3
> prepare
function(x) { p = function(x) 5*x; q= function(x) x^2 }
> with( new.env ( eval( parse(text=deparse(body(prepare))) ) ) , { print(p(5)); print(q(2))} )
[1] 25
[1] 4
prepare = function() {
f = function(x) x+1
g = function(x) x+2
}
my_function = function(preparefun) {
# We call the prepare() function supplied by the user
# that defines functions f() and g() and store its returned value
# (WHICH IS A FUNCTION)
fun_returned_by_prepare = preparefun()
cat("Result of calling function f(3) defined in function prepare():", environment(fun_returned_by_prepare)$f(3), "\n")
cat("Result of calling function g(3) defined in function prepare():", environment(fun_returned_by_prepare)$g(3), "\n")
}
my_function(prepare)
Result of calling function f(3) defined in function prepare(): 4
Result of calling function g(3) defined in function prepare(): 5