【问题标题】:How to handle unknown methods/generics in R如何处理 R 中的未知方法/泛型
【发布时间】:2019-06-19 13:12:39
【问题描述】:

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

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

【问题讨论】:

  • 您想做什么某事

标签: r oop s4 r6


【解决方案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”

Here some infos about OO-programing in R.

【讨论】:

  • 谢谢!我假设它对 S4 的工作原理是正确的吗?从 S3 到 S4 的转换似乎有很多。
  • 上面的链接(在我的回答中)属于处理所有类型的 OO 系统的页面,您会在那里找到很多关于 S4 的信息以及一些指向更多信息源的链接。您可以使其适用于 S4,但在我看来,对于您想要做的事情,它不像 S3 那样简单。
  • 我试了一下,但现在我很清楚它处理未知的类——而不是未知的方法。在这种情况下,“mean”是一种已知方法,而“default”是一种后备方法,以防类不是数字、data.frame 或矩阵。我真正想要的是捕捉是否有人在我没有平均方法的对象上调用“平均”。
  • @KyleWard 我编辑了我的答案,希望现在很清楚;)
【解决方案2】:

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 中那样从类定义中执行此操作的标准方法。

【讨论】:

  • 这只是重复 jkd 在他们的回答中所说的话
  • 不,这不是重复 jkd 的答案。这解决了 jkd 最后提出的关于找不到相应字段或方法的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-20
  • 2019-05-20
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多