首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果是R函数,是否是环境的父环境也是环境的父环境?

如果是R函数,是否是环境的父环境也是环境的父环境?
EN

Stack Overflow用户
提问于 2020-08-28 06:50:40
回答 1查看 75关注 0票数 2

假设我创建了一个环境(E)的父环境(E2 <= environment E1 <= environment E)。我的问题是,E2是否也是E的父级。对我来说,答案是肯定的,但下面的代码似乎正好相反。

怎么啦?参见下面可重复的示例中的最后一行,其中print(parent-parent)生成

# [1] FALSE # I would expect a TRUE here!!

从docs ?parent.env

如果您遵循通过从任何环境中反复调用parent.env找到的封闭链,则最终会到达空环境emptyenv(),在该环境中不可能分配任何内容。

代码语言:javascript
复制
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)))
  # print(parent.env(env)) # <environment: R_GlobalEnv>??
  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()
# [1] "fun1"
# [1] "===="
# [1] TRUE #     OK
# [1] FALSE
# [1] FALSE
# [1] " subfun"
# [1] " ======"
# [1] FALSE
# [1] TRUE #     OK
# [1] FALSE
# [1] "  subsubfun"
# [1] "  ========="
# [1] FALSE
# [1] FALSE
# [1] FALSE #    I would expect a TRUE here!!
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-28 09:06:45

问题是,实际上是在全局环境中定义所有函数,因此它们的父函数就是全局环境。

如果在其他函数中定义函数,则可以得到所期望的结果。请看下面的示例。

(此外,我还创建了一个打印所有父环境直到全局环境的函数)

代码语言:javascript
复制
env_genealogy <- function(env){
    
    while(!identical(env, globalenv())){
        
        env <- parent.env(env)
        print(env)
        
    }
    
}



fun1 <- function() {
    subfun0 <- function() {
        
        print(" subfun0")
        print(" ======")
        
        env_genealogy(environment())
        
        e <- parent.frame()
        attr(e, "name") <- "my_env"
        assign("my_env", 1,
                     envir = parent.frame(),
                     inherits = FALSE, immediate = TRUE)
        return(NULL)
    }
    
    
    subfun <- function() {
        
        subsubfun <- function() {
            print("  subsubfun")
            print("  =========")
            
            env_genealogy(environment())
            
            print(exists("my_env"))
            print(exists("my_env", parent.frame()))
            env <- parent.frame()
            print(exists("my_env", parent.env(env)))
            # print(parent.env(env)) # <environment: R_GlobalEnv>??
            return(NULL)
        }
        
        print(" subfun")
        print(" ======")
        
        env_genealogy(environment())
        
        print(exists("my_env"))
        print(exists("my_env", parent.frame()))
        env <- parent.frame()
        print(exists("my_env", parent.env(env)))
        subsubfun()
        return(NULL)
    }
    
    
    
    print("fun1")
    print("====")
    
    env_genealogy(environment())
    
    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()
代码语言:javascript
复制
[1] "fun1"
[1] "===="
<environment: R_GlobalEnv>
[1] " subfun0"
[1] " ======"
<environment: 0x000001b0e4b124d8>
<environment: R_GlobalEnv>
[1] TRUE
[1] FALSE
[1] FALSE
[1] " subfun"
[1] " ======"
<environment: 0x000001b0e4b124d8>
attr(,"name")
[1] "my_env"
<environment: R_GlobalEnv>
[1] TRUE
[1] TRUE
[1] FALSE
[1] "  subsubfun"
[1] "  ========="
<environment: 0x000001b0e552add0>
<environment: 0x000001b0e4b124d8>
attr(,"name")
[1] "my_env"
<environment: R_GlobalEnv>
[1] TRUE
[1] TRUE
[1] TRUE
NULL

有关更多细节,请看一看这里

对于一个最小的例子,您可以查看以下内容:

代码语言:javascript
复制
a <- function(){
    
    i
    
}
 
a()
> #> Error in a() : object "i" not found

b <- function(){
    
    i <- 1
    
    a()
    
}
b()
> #> Error in a() : object "i" not found
 
d <- function(){
    
    i <<- 1
    a()
    
}
d()
#> [1] 1
rm(i)
 
 
f <- function(){
    
    g <- a
    i <- 2
    g()
    
}
f()
#> Error in g() : object "i" not found

h <- function(){
    
    l <- function() i
    i <- 2
    l()
    
}
h()
#> [1] 2

当您调用a()时,会得到一个错误,因为没有定义i

即使在i中定义b(),也会出现相同的错误,因为b的环境不与a共享,这就是您的情况。

d()之所以有效,是因为我们用<<-i分配给全局环境。

f()不起作用:即使我们在f中定义了g,我们也复制了一个复制它的父环境的a副本。

我们在h()中得到了一个结果,因为l()是在里面定义的。这就是我在回答中给你看的情况。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63628854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档