范围——如果存在同名的本地变量,如何评估父环境中的对象?
Posted
技术标签:
【中文标题】范围——如果存在同名的本地变量,如何评估父环境中的对象?【英文标题】:Scope -- how to evaluate an object in parent environment if local var with same name exists? 【发布时间】:2012-11-19 02:49:47 【问题描述】:如果我有两个嵌套环境使用相同的变量名,我将如何获取外部环境的值?
我很难找出实现这一点的正确方法。我在 eval 中尝试了 parent.frame(x)
和 sys.frame(x)
的一些变体。任何建议,将不胜感激。
示例:
outerFunc <- function()
obj <- "Outer Object"
innerFunc()
innerFunc <- function()
# A local variable with same name is created
obj <- "Inner Object"
# would like to grab the value of obj from the outer environment
obj.callingFunc <- eval(obj, envir=sys.frame(-1))
cat(obj.callingFunc) # gives "Inner Object" instead of "Outer Object"
> outerFunc()
Inner Object
在这种特定情况下,我无法使用明显的解决方案(明确传递 obj
。使用不同的变量名等)。
编辑
检查下面@GregSnow 和@Dwin 的答案
# THESE WORK
eval(quote(obj), envir=parent.frame()) # equivalent to evalq(obj, envir=parent.frame())
get("obj", envir=parent.frame())
# THESE DO *NOT* WORK
eval("obj", envir=parent.frame())
get(quote(obj), envir=parent.frame())
对于在get()
与eval()
中引用的效果有何想法?
【问题讨论】:
您能解释一下为什么没有明显的解决方案吗?感觉就像您在向我们询问有关解决实际问题的特定方法的问题,而不是告诉我们您的真正问题。也许有更好的方法。 @Aaron,我希望完成的是学习如何在不同环境中使用变量。我最后的评论是避免提供提供相同最终结果但不提供知识的变通方案的诱惑:) 上述功能只是为了测试和学习,并不代表手头的任何问题。 里卡多:我为你的努力喝彩。 R 评估的内部工作是一个很少有人理解的领域(我不包括我自己在理解它的小组中)。我猜可能有 50 到 200 之间的一些数字可以很好地理解它。 引用时:get
接受字符串作为输入,eval
接受调用或表达式。向函数提供错误的输入不太可能使其工作。
【参考方案1】:
outerFunc <- function()
obj <- "Outer Object"
innerFunc()
innerFunc <- function()
# A local variable with same name is created
obj <- "Inner Object"
# would like to grab the value of obj from the outer environment
cat( get('obj', envir=parent.frame()) )
outerFunc()
#Outer Object
也可以使用:eval(quote(obj), envir=sys.frame(-1))
。很明显,quote(expr) 的含义与“expr”的含义不同。 get
函数“期望”(或者更准确地说是设计)接收字符值,而 eval
期望调用和表达式,即“语言”对象。 R 中的数据和语言之间有一种半透膜,get
是一种膜通道,您可以通过它将字符值对象传递到语言域。
【讨论】:
一如既往地感谢您的详细回复。 +1 将我指向语言对象,这有助于澄清quote()
的返回值
我认为在评论中使用“调用”环境而不是“外部”环境会有所帮助 - 您需要区分词法范围(即如何定义函数)和动态范围(函数如何被称为)。外部环境有点模棱两可。【参考方案2】:
将您的 eval
更改为 evalq
或在调用 eval 时引用 obj
。正如 obj 在将其提供给 eval
之前对其进行评估一样,因此它具有内部值,引用它说将表达式(而不是值)传递给 eval
以进行评估。
【讨论】:
@RicardoSaporta,引用我的意思是eval(quote(obj), ...
。我应该更具体。以上是关于范围——如果存在同名的本地变量,如何评估父环境中的对象?的主要内容,如果未能解决你的问题,请参考以下文章