从函数内部将函数环境设置为调用环境(parent.frame)的环境

Posted

技术标签:

【中文标题】从函数内部将函数环境设置为调用环境(parent.frame)的环境【英文标题】:Set a functions environment to that of the calling environment (parent.frame) from within function 【发布时间】:2014-07-16 10:21:10 【问题描述】:

我仍在为 R 范围界定和环境而苦苦挣扎。我希望能够构建从我的“主”函数中调用的简单辅助函数,这些函数可以直接引用这些主函数中的所有变量——但我不想在我的每个主函数中定义辅助函数职能。

helpFunction<-function()
#can I add a line here to alter the environment of this helper function to that of the calling function?
return(importantVar1+1)


mainFunction<-function(importantVar1)
return(helpFunction())


mainFunction(importantVar1=3) #so this should output 4

【问题讨论】:

【参考方案1】:

如果您将每个函数声明为在 mainfunction 的开头使用动态范围,如下例所示,它将起作用。使用问题中定义的helpFunction

mainfunction <- function(importantVar1) 

    # declare each of your functions to be used with dynamic scoping like this:
    environment(helpFunction) <- environment()

    helpFunction()


mainfunction(importantVar1=3)

辅助函数本身的源码不需要修改。

顺便说一句,您可能想研究一下 Reference Classes 或 proto 包,因为您似乎正试图通过后门进行面向对象的编程。

【讨论】:

【参考方案2】:

嗯,一个函数不能改变它的默认环境,但你可以使用eval 在不同的环境中运行代码。我不确定这是否完全符合优雅的条件,但这应该可行:

helpFunction<-function()
    eval(quote(importantVar1+1), parent.frame())


mainFunction<-function(importantVar1)
    return(helpFunction())


mainFunction(importantVar1=3)

【讨论】:

谢谢。这有时会有所帮助 - 格洛腾迪克的答案非常相似,但我喜欢单线方法。【参考方案3】:

R 方式是传递函数参数:

helpFunction<-function(x) 
#you can also use importantVar1 as argument name instead of x
#it will be local to this helper function, but since you pass the value
#it will have the same value as in the main function
  x+1


mainFunction<-function(importantVar1)
  helpFunction(importantVar1)


mainFunction(importantVar1=3)
#[1] 4

编辑,因为您声称它“不起作用”:

helpFunction<-function(importantVar1) 
  importantVar1+1


mainFunction<-function(importantVar1)
  helpFunction(importantVar1)


mainFunction(importantVar1=3)
#[1] 4

【讨论】:

没有其他解决方案了吗?当许多变量需要任意重命名时,这种方法会变得非常令人厌烦......使辅助函数变得不太有用。 我看不出这种方法需要重命名变量吗?如果您将变量名称硬编码到您的辅助函数中,这似乎不是很有用。 我正在开发一个包,它在我猜的有限范围的变量上做了很多不同的事情。例如,我有一个与每个函数相关的 timepoints 变量,为每个函数重新定义它很麻烦。 我还是不明白你为什么认为你需要重新定义任何东西?我同意@G.Grothendieck,听起来你想为它创建一个对象和一堆方法。用 R 研究面向对象的编程。 你仍然没有让我明白你想要什么以及为什么这是一个好主意(除了在编写函数时可能输入更少的字符?)。

以上是关于从函数内部将函数环境设置为调用环境(parent.frame)的环境的主要内容,如果未能解决你的问题,请参考以下文章

javascript闭包

如何将许多变量和函数从全局环境导出到 foreach 循环?

将连接字符串设置为Azure函数中的应用设置/环境变量

闭包的理解

执行环境作用域作用域链调用对象闭包

调用ViewGroup的addView之后,是怎样显示出来的