[英]Is in case of R functions a parent's parent environment of an environment also parent to the environment?
假設,我創建了一個環境 (E) 的父級父環境 (E2 <= environment E1 <= environmet E)。 我的問題是,E2 是否也是 E 的父級。對我來說很明顯,答案是肯定的,但以下代碼似乎相反。
怎么了? 請參閱下面可重現示例中的最后一行,其中print(parent-parent
) 產生
# [1] FALSE # I would expect a TRUE here!!
從文檔?parent.env
如果遵循通過從任何環境重復調用 parent.env 找到的外殼鏈,最終會到達空環境 emptyenv(),其中可能沒有分配任何內容。
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!!
問題是您實際上是在全局環境中定義所有函數,因此它們的父級是全局環境。
如果你在其他函數中定義你的函數,你會得到你所期望的。 看看下面的例子。
(我還創建了一個打印所有父環境直到全局環境的函數)
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()
[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
有關更多詳細信息,請查看此處
對於一個最小的例子,你可以看看這個:
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
未定義。
即使你在b()
定義i
你也會得到同樣的錯誤,因為b
的環境不與a
共享。 這是你的情況。
d()
有效,因為我們使用<<-
將i
分配給全局環境。
f()
不工作:即使我們定義g
內f
,我們做的副本a
也復制其父環境。
我們在h()
得到結果,因為l()
是在其中定義的。 這就是我在回答中向您展示的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.