范围——如果存在同名的本地变量,如何评估父环境中的对象?

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), ...。我应该更具体。

以上是关于范围——如果存在同名的本地变量,如何评估父环境中的对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查操作系统变量并将它们与列表中的 Python 变量同名使用

传入null时,JSP标记属性从父范围继承变量?

第47课 父子间的冲突

linux基础命令Ⅱ

在类范围内声明一个与类属性同名的局部变量

在 ColdFusion UDF 中,有没有办法从父函数范围引用变量?