如何在 R 中处理未知 methods/generics

How to handle unknown methods/generics in R

许多语言都有处理未知方法的特殊方法 (examples)。我最熟悉的是Python的__getattr__。如果有人调用了您尚未为 class 定义的方法,__getattr__ 将充当包罗万象的角色并执行 某事 .

我一直在阅读 S4 和 R6 的一些内容,但我还没有找到如何在 R 中执行此操作。这可能吗?

不,没有像在 python.

中那样从 class 定义中执行此操作的标准方法

在 python 中你会做类似 MyObject.my_method() 的事情,而在 R 中使用 S3 或 S4 这将是 my_method(MyObject) 所以它看起来完全一样喜欢 my_function(MyObject)。唯一的区别是,在幕后,您调用的函数将调用分派给适当的方法。为多个 classes 定义这些方法如下:

mean <- function (x, ...) UseMethod("mean", x)
mean.numeric <- function(x, ...) sum(x) / length(x)
mean.data.frame <- function(x, ...) sapply(x, mean, ...)
mean.matrix <- function(x, ...) apply(x, 2, mean)
mean.default <- function(x, ...) {
  # do something
}

但是,如果您在未定义任何方法的 class 上调用 mean 函数,则由函数来处理,而不是 class.

然后你有 RC 和 S6 对象,它们有更多 python-like 语法(MyObject$my_method()),但是它们只会抛出一个错误您使用的 class 没有相应的字段或方法。

Error in envRefInferField(x, what, getClass(class(x)), selfEnv) : 
  "my_method" is not a valid field or method name for reference class “MyObject”

Here some infos about OO-programing in R.

Winston Chang 在这里提供了很好的信息:
https://github.com/r-lib/R6/issues/189#issuecomment-506405998

他解释了如何为 class 创建 S3 通用函数 $ 以捕获未知方法。阅读他的完整回复以获取更多详细信息,但关键功能在下面(Counter 是 class 的名称)。

`$.Counter` <- function(x, name) {
  if (name %in% names(x)) {
    .subset2(x, name)
  } else {
    function(...) {
      .subset2(x, "do")(name, ...)
    }
  }
}

"If name is in the class, do that. If not, send name (and any arguments) to a function called do() defined in the class."

虽然我已将此标记为答案(因为它解决了问题),jkd 仍然正确:

No there is no standard way of doing this from inside your class definition as you would do in python.