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

And*_*ter 7 r

print我试图为我的新对象定义 print 方法,并使用传递给using的对象名称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"
Run Code Online (Sandbox Code Playgroud)

但是,当对象本身通过名称调用时,生成的print函数不会检测到该名称:

obj
# New object name:
#   [1] "x"
Run Code Online (Sandbox Code Playgroud)

print当单独传递对象名称时,是否有一种标准方法可以更改隐式调用的行为?

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

All*_*ron 3

解释发生了什么比解决它更容易。如果我们首先查看泛型,我们可以看到它只是通过以下方式print调度适合类的方法:printUseMethod("print")

print
#> function (x, ...) 
#> UseMethod("print")
Run Code Online (Sandbox Code Playgroud)

因此,当您调用 时,您首先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
Run Code Online (Sandbox Code Playgroud)

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

obj当您在控制台中输入内容时,现在会发生什么?

obj
#> [[1]]
#> (function (x, ...) 
#> UseMethod("print"))(x)
#> 
#> [[2]]
#> print.new_obj(x)
#> 
#> New object name:
#> x
Run Code Online (Sandbox Code Playgroud)

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

obj
#> [[1]]
#> (function (x, ...) 
#> UseMethod("print"))(x)
#> 
#> [[2]]
#> print.new_obj(x)
#> 
#> New object name:
#> x
Run Code Online (Sandbox Code Playgroud)

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

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