gpt4 book ai didi

r - 直接调用对象时获取传递给 `print`的对象名称(不表达 `print`函数)

转载 作者:行者123 更新时间:2023-12-04 13:37:19 26 4
gpt4 key购买 nike

我正在尝试为我的新对象定义打印方法,并使用传递给 print 的对象名称。使用 deparse(substitute(y)) .这可以完美地使用 print功能明确:

obj <- structure(list(x = 1), 
class = "new_obj")

print.new_obj <- function(y){
cat("New object name:\n")
print(deparse(substitute(y)))
}

print(obj)
# New object name:
# [1] "obj"

但是当对象自己按名称调用时,结果 print函数未检测到名称:
obj
# New object name:
# [1] "x"

是否有标准方法可以更改对 print 的隐式调用的行为?自己传递对象名称时?

编辑:已将函数参数更改为 y表示正在传递的对象,以证明无论在第二次调用中如何返回“x”。

最佳答案

解释正在发生的事情比修复它更容易。如果我们从通用 print 开始我们可以看到它只是简单地调度了适合类的 print方法通过 UseMethod("print") :

print
#> function (x, ...)
#> UseMethod("print")

所以当你拨打 print(obj) ,您正在调用泛型函数 print(obj)首先,然后调用 print.new_obj(obj) .我们可以通过添加 print(sys.calls()) 来确认这一点。到您的打印方法:

print.new_obj <- function(y){
print(sys.calls())
cat("New object name:\n")
cat(deparse(substitute(y)))
}

print(obj)
#> [[1]]
#> print(obj)
#>
#> [[2]]
#> print.new_obj(obj)
#>
#> New object name:
#> obj

到目前为止,一切都很好,我怀疑你已经知道这一切。

现在会发生什么,当你输入 obj 时进入控制台?
obj
#> [[1]]
#> (function (x, ...)
#> UseMethod("print"))(x)
#>
#> [[2]]
#> print.new_obj(x)
#>
#> New object name:
#> x

现在我们可以看到 x 在哪里来自。它取自对通用 print 的幕后调用。它实际上被称为一个未命名的函数。因此,变量的名称实际上并未包含在调用堆栈中。 SO上还有其他问题,它说这使问题无法解决。这不是真的。这只是意味着您需要查看对象的调用堆栈之外:

print.new_obj <- function(y){
obj_name <- deparse(substitute(x, parent.frame()))
if (obj_name != "x")
{
obj_name <- names(which(sapply(ls(envir = parent.frame(2)), function(v)
identical(y, get(v, envir = parent.frame(2))))))[1]
cat("New object name:\n", obj_name)
}
else cat("New object name:\n", deparse(substitute(y)))
}

print(obj)
#> New object name:
#> obj
obj
#> New object name:
#> obj

当然,出于各种原因,您不希望在生产代码中使用它。对于数据结构来说,知道它在特定环境中被分配了什么名称并不是特别有用或合乎逻辑,也不是为其他用户编写包的惯用方式。

不过,很高兴知道这是可能的。

关于r - 直接调用对象时获取传递给 `print`的对象名称(不表达 `print`函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61059080/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com