给定一个已在R包中定义的S4类的对象:
如何可靠地找出S4对象的包名(命名空间)?
# Create a class in the global env
MyS4Class <- setClass("MyS4Class", slots = c(name = "character"), prototype = list(name = "unknown"))
class(MyS4Class)
# [1] "classGeneratorFunction"
# attr(,"package")
# [1] "methods"
obj <- new("MyS4Class")
class(obj)
# [1] "MyS4Class"
# attr(,"package")
# [1] ".GlobalEnv"
# Get an instance of a S4 class from a package
library(odbc)
obj2 <- odbc::odbc()
# isS4(obj2)
# [1] TRUE
class(obj2)
# [1] "OdbcDriver"
# attr(,"package")
# [1] "odbc"
看起来package
属性总是填充命名空间名称但是偶然或设计?
PS:可以通过attr(class(obj2), "package")
答案 0 :(得分:1)
这是设计的。来自Section 1.12.1 of the R Internals Manual:
通过new()创建S4对象,然后通过C函数创建 R_do_new_object。这复制了类的原型,添加了一个 class属性并设置S4位。所有S4类属性都应该是 具有属性给出的长度为1的字符向量(作为 字符串)包含的包(或.GlobalEnv)的名称 类定义。
我们可以放心,S4对象的class属性将具有package属性,尽管从技术上讲,package属性的值可能不正确。查看R_do_new_object
here的C代码,无论何时创建S4对象,都会按类定义中的定义设置class属性。查看setClass
的R代码(及其调用的函数,makeClassRepresentation
,assignClassDef
和classGeneratorFunction
),将始终分配包属性,但默认值(这就是你所追求的)技术上可以自定义指定为setClass()
的参数;来自help("setClass")
:
package:为类提供可选的包名,但是 class属性应该是类定义所在的包 默认情况下已分配。
假设在定义类时指定了这个,或者在定义类时未指定(在这种情况下默认值将提供正确的值),您应该能够使用{{{}来可靠地获取包名称。 1}}。