r - 列表中的函数可以访问 R 中列表的属性吗?
问题描述
在以下示例中,列表中的函数应返回字符串"The value currently is 42"
。
l <- list(
param = 42,
f = function() { paste("The value currently is", param) }
)
(示例灵感来自 Mozilla 的关键字this的 js 文档)
显然调用l$f()
失败是因为object 'param' not found
.
ls.str()
我尝试使用和检查环境中可用的对象ls()
。我找到的最接近的解决方案是引用分配给列表的变量名称。
l <- list(
param = 42,
f = function() { paste("The value currently is", l$param) }
)
这当然不是最理想的,因为变量可以命名为任何东西。
里面的函数有没有办法l
引用它的相邻属性param
?如果没有,是否有一些嵌套的更复杂的解决方案可以完成类似的任务?
解决方案
您可以match.call
在函数内部使用从用于访问函数的子集调用中捕获列表的名称。如果您eval
在父框架中使用此符号,则您有一个 (dereferenced) 的等价物this
。
这给出了所需的行为,如以下表示所示:
l <- list(a = 1,
f = function() {
mc <- match.call()
this_sym <- as.list(as.list(mc)[[1]])[[2]]
this <- eval(this_sym, envir = parent.frame())
cat("Value of ", as.character(this_sym), "$a is ", this$a, sep ="")
})
l$f()
#> Value of l$a is 1
l$a <- 42
l$f()
#> Value of l$a is 42
new_list <- l
new_list$f()
#> Value of new_list$a is 42
然而,这感觉就像是在尝试使用一个普通的列表来复制那种已经可以用 R6 或 S4 类做得更好的面向对象编程。
由reprex 包(v0.3.0)于 2020-07-17 创建
推荐阅读
- api - 开放的天气 api 数据正在进入第一个控制器,但我想在另一个带有标签的控制器中显示城市和温度湿度。如何?
- python - Python(硒)循环
- c - 从 WinAPI C 中的 "1 + 1" = 2 之类的字符串计算数据
- sum - PowerBI - 如何让 DAX 函数与过滤器/条件相加?
- ubuntu - 未找到时间戳 proto 和其他 proto 文件,即使它们存在于 /usr/local/bin/include/google/protobuf
- airflow - 使用 Airflow,从同一个循环中,成功的 API 响应继续执行下一个任务,但带有错误的响应具有单独的任务,显示为失败
- .net - SoapCore 读Soap1.1
- selenium - Heroku上的硒超时
- postgresql - Postgres与spring数据的相似性函数
- python - 如何使用 Inventor API 和 Python 访问装配体中出现的工作平面