直接调用对象时获取传递给'print'的对象名称(不表示'print'函数)

直接调用对象时获取传递给'print'的对象名称(不表示'print'函数),r,R,我正在尝试为我的新对象定义打印方法,并使用deparse(替换(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

我正在尝试为我的新对象定义打印方法,并使用
deparse(替换(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
的隐式调用的行为


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

解释发生了什么比修复它更容易。如果我们从查看泛型的
print
开始,我们可以看到它只是通过
UseMethod(“print”)
分派类相应的
print
方法:

打印
#>函数(x,…)
#>使用方法(“打印”)
因此,当您调用
print(obj)
时,首先调用通用函数
print(obj)
,然后调用
print.new\u obj(obj)
。我们可以通过在打印方法中添加
print(sys.calls())
来确认这一点:

print.new_obj[[1]]
#>打印(obj)
#> 
#> [[2]]
#>打印新的_obj(obj)
#> 
#>新对象名称:
#>obj
到目前为止,一切顺利,我想你已经知道了这一切

当您在控制台中键入
obj
时,现在会发生什么

obj
#> [[1]]
#> (function (x, ...) 
#> UseMethod("print"))(x)
#> 
#> [[2]]
#> print.new_obj(x)
#> 
#> New object name:
#> x
现在我们可以看到
x
来自何处。它来自对泛型
print
的幕后调用,该函数实际上被称为未命名函数。因此,变量的名称实际上不包括在调用堆栈中。还有其他问题,所以它说这使得问题无法解决。这不是真的;这只意味着您需要在调用堆栈之外查找对象:

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


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

标准方法是您已经发现的方法
deparse(substitute(x))
在这两种情况下,它都是通过
print.new_obj
函数调用
deparse(substitute(x))
,但在第二种情况下,它将一个“x”伪对象或某些东西传递给调用,并返回“x”,而不管对象的名称如何。函数参数表示为非
x
(仍然返回“x”)时的行为相同。Eli Holmes的回答表明,这种行为可能是不可避免的:感谢Allan,这是一个非常有用的见解-知道
print(sys.calls())
可以跟踪所做的事情非常方便。我根本不知道如何找出print方法是如何被调用的。这是一种简便有趣的解决方法,但我认为你是对的——也许根本不用这么做。这是为了提示包用户如何访问包含的数据(但不是打印出来的)。我们将研究指向这一点的其他方法。
obj
#> [[1]]
#> (function (x, ...) 
#> UseMethod("print"))(x)
#> 
#> [[2]]
#> print.new_obj(x)
#> 
#> New object name:
#> x