1

许多语言都有处理未知方法的特殊方法(示例)。我最熟悉的是 Python 的__getattr__. 如果有人调用了您尚未为该类定义的方法,则__getattr__充当包罗万象并执行某些操作。

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

4

2 回答 2

1

不,没有像在 python 中那样从类定义中执行此操作的标准方法。

在 python 中,你会MyObject.my_method()在 R 中使用S3 或 S4执行类似操作,这样my_method(MyObject)它看起来就像my_function(MyObject). 唯一的区别是,您调用的函数将调用分派给适当的方法。为多个类定义这些方法如下:

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
}

但是,如果你在一个没有定义方法的类上调用 mean 函数,则由函数来处理这个,而不是类。

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

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

这里有一些关于 R 中的 OO 编程的信息

于 2019-06-19T13:36:37.160 回答
0

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

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

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

“如果name在类中,请执行此操作。如果不是,则将name(和任何参数)发送到类中定义的调用函数do()。”

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

不,没有像在 python 中那样从类定义中执行此操作的标准方法。

于 2019-06-27T17:47:57.717 回答